博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
汇编实验十:编写子程序
阅读量:7048 次
发布时间:2019-06-28

本文共 5070 字,大约阅读时间需要 16 分钟。

预备知识:

(1)

ret  :修改IP  IP = SS*16 + SP   SP+=2

retf :修改CS,IP  IP = SS*16 + SP ,SP+=2 , CS = SS*16 + SP , SP+=2

Source Code:

 

assume cs:codestack segment    db 16 dup (0)stack endscode segment    mov ax,4c00H    int 21H    start:        mov ax,stack        mov ss,ax        mov sp,16        mov ax,0        push ax        mov bx,0        retcode endsend start
View Code

 

 

IP指向了栈顶元素,栈顶元素等于0,那么下一条命令就是返回程序;

 

Source Code:

assume cs:codestack segment    db 16 dup (0)stack endscode segment    mov ax,4c00h    int 21hstart:    mov ax,stack    mov ss,ax    mov sp,16    mov ax,0    push cs    push ax    mov bx,0    retfcode endsend start
View Code

IP还是指向栈顶元素,下一条命令是返回程序;

也就是说,

ret 相当于 pop IP;

retf 相当于 pop IP,pop CS;

 

(2)call:内存中转移

call word ptr 相当于 push IP,jmp word ptr

call dword ptr 相当于 push CS,push IP,jmp dword ptr

 

Source Code:

assume cs:codestack segment    dw 8 dup (0)stack endscode segmentstart:    mov ax,stack    mov ss,ax    mov sp,16    mov ds,ax    mov ax,0    call word ptr ds:[0EH]    inc ax    inc ax    inc ax    mov ax,4c00H    int 21Hcode endsend start
View Code

 

 

(3)mul,乘法指令

1、8位,一个数在AL中,一个在内存中,结果在AX中

2、16位,一个在AX中,一个在内存中,结果,高位在DX中,低位在AX中;

 

 

(4)call和ret的配合:模块化程序

 Source Code:

assume cs:codedata segment    dw 1,2,3,4,5,6,7,8    dd 0,0,0,0,0,0,0,0data endscode segmentstart:    mov ax,data    mov ds,ax    mov si,0    mov di,16    mov cx,8    s:        mov bx,[si]        call cube        mov [di],ax        mov [di].2,dx        add si,2        add di,4        loop s    mov ax,4c00H    int 21Hcube:    mov ax,bx    mul bx    mul bx    retcode endsend start
View Code

 

(5)批量数据传递,放到内存中,或者栈中;

 Source Code:

assume cs:codedata segment    db 'conversation'data endscode segmentstart:    mov ax,data    mov ds,ax    mov si,0    mov cx,12    call capital    mov ax,4c00h    int 21hcapital:    and byte ptr [si],11011111b    inc si    loop capital    retcode endsend start
View Code

 

(6)解决寄存器的冲突,就是将子程序用到的寄存器入栈;

Source Code:

assume cs:codedata segment    db 'word',0    db 'unix',0    db 'wind',0    db 'good',0data endscode segmentstart:    mov ax,data    mov ds,ax    mov bx,0    mov cx,4    s:        mov si,bx        call capital        call change        add bx,5        loop s    mov ax,4c00h    int 21h    capital:        push cx        push si    change:        mov cl,[si]        mov ch,0        jcxz ok        and byte ptr [si],11011111b        inc si        jmp short capital    ok:        pop si        pop cx        retcode endsend start
View Code

 

试验任务:

显示字符串(注意DOS下一列占两个字符)

Source Code:

assume cs:codedata segment    db 'I am TreeDream!',0data endscode segmentstart:    mov dh,8    mov dl,3    mov cl,2    mov ax,data    mov ds,ax    mov si,0    call show_str    mov ax,4c00H    int 21Hshow_str:    push dx    push cx    push ax    push ss    push si    mov ax,0B800H    mov es,ax   ;用于显示的栈段    mov al,0a0h    dec dh      ;行数以0标号    mul dh      ;行的偏移    mov bx,ax    mov al,2    ;dos显示一列占两个字节    dec dl    mul al    add bx,ax   ;显示的起始地址计算完    mov di,0    ;数据段指针    mov si,0    mov al,cl   ;cx用于循环s:    mov ch,0    mov cl,ds:[di]    jcxz ok     ;判断cx是否为0    mov ch,al    mov es:[bx+si],cx   ;显示    add si,2    inc di    jmp short sok:    pop si    pop ss    pop ax    pop cx    pop dx    retcode endsend start
View Code

 

 

(2)除法溢出

assume cs:code,ss:stackstack segment    dw 8 dup (0)stack endscode segmentstart:    mov ax,stack    mov ss,ax    mov sp,16    mov ax,1000H    mov dx,1    mov bx,1    div bx    mov ax,4c00h    int 21hcode endsend start
View Code

除法的结果超过16为,ax中存不下;

解决方案,公式是X/N = int(H/N)*65536 + (rem(H/N)*65536 + L) / N

公式很好理解,但是程序不是很好理解;

Source Code:

assume cs:code,ss:stackstack segment    dw 8 dup (0)stack endscode segmentstart:    mov ax,stack    mov ss,ax    mov sp,16    mov ax,4240H    mov dx,00fH    mov cx,0aH    call divdw    mov ax,4c00h    int 21hdivdw:    push ax    mov ax,dx    mov dx,0    div cx    mov bx,ax    pop ax    div cx    mov cx,dx    mov dx,bx    retcode endsend start
View Code

 

 

第一次除法:

ax = 1,dx = 5

 

 第二次除法的时候,第一次的除法余数将是第二次除法的高位

 

(3)数值显示

Source Code:

assume cs:codedata segment    db 10 dup (0)data endsstack segment    dw 8 dup(0)stack endscode segmentstart:    mov ax,42243    mov bx,data    mov ds,bx    mov bx,stack    mov ss,bx    mov sp,10h    mov si,0    call dtoc    mov dh,8    mov dl,3    mov cl,2    call show_str    mov ax,4c00h    int 21hdtoc:    push ax    push bx    push si    mov bx,10    mov si,0s0:    mov dx,0    div bx  ;dx 余数,ax商    add dx,30h  ;余数入栈    push dx    mov cx,ax   ;一直除到商为0    inc si    inc cx      ;每次循环cx会减1,然而cx是用来存商的;    loop s0    mov cx,si   ;cx循环次数,即有多少位    mov si,0s1:    pop ds:[si]    inc si    loop s1    pop si    pop bx    pop ax    retshow_str:    push ax    push dx    push cx    push si    mov di,0    mov bl,dh    dec bl    mov al,160    mul bl    mov bx,ax    add dl,dl    add bl,dl    mov ax,0b800h    mov es,ax    mov al,cls:    mov ch,0    mov cl,ds:[si]    jcxz ok    mov es:[bx+di],cl    mov es:[bx+di+1],al    add di,2    inc si    loop sok:    pop si    pop cx    pop dx    pop ax    retcode endsend start
View Code

 

转载于:https://www.cnblogs.com/TreeDream/p/6929840.html

你可能感兴趣的文章
利用Fitbit,十秒入侵PC
查看>>
达沃时代田大庆:融合存储是趋势
查看>>
提高 Java 代码性能的各种技巧
查看>>
大数据和警察
查看>>
施耐德电气:打造新一代数据中心基础设施
查看>>
土地紧张使香港数据中心市场增长乏力
查看>>
域名选择的六大技巧
查看>>
【过程改进】总结大中小型项目的git流程
查看>>
“十三五”输电通道规模倍增 重点建设配电网
查看>>
新区发力“互联网+”政务服务 云平台互联互通
查看>>
简述数据中心四种数据备份方式
查看>>
《编写高质量Python代码的59个有效方法》——第17条:在参数上面迭代时,要多加小心...
查看>>
《Node.js区块链开发》导读
查看>>
理解RESTful架构
查看>>
《响应式Web设计全流程解析》一1.4 我们都是交互设计师
查看>>
深入实践Spring Boot2.1.1 MySQL依赖配置
查看>>
Java面试 机试题01
查看>>
Guarded Suspension
查看>>
搞大数据,需要关注的东西
查看>>
致敬那些运维过程中踩到的坑
查看>>