第十章检测实验及笔记
本帖最后由 yundi 于 2016-1-8 14:49 编辑先来个实验10的第2题,解决除法溢出问题。
一张图理顺寄存器变化
;不溢出的除法子程序
;自己发明的表示法:(dx)(ax)/(cx)=(dx)(ax)...(cx)
assume cs:code
code segment
start: mov dx,000fh
mov ax,4240h
mov cx,0ah
call divdw
mov ax,4c00h
int 21h
divdw:
;1.先处理被除数高16位(dx)的除法
push bx;子程序用到的寄存器,先入栈保存
push ax;被除数低16位(ax)后面要用,也保存到栈中
mov ax,dx;因为除数(cx)16位,所以把高16位放到(ax)
xor dx,dx;同时让(dx)为0
div cx;然后相除(dx)(ax)/(cx)=(ax)...(dx)
;2.再处理被除数低16位(ax)的除法
pop bx;被除数低16位出栈
push ax;栈保存高16位除后的商
;现在的(dx)保存高16位除后的余数,正好下步可用
;公式中余数*65536,为何此处(dx)不乘?
mov ax,bx
div cx;(dx)(ax)/(cx)=(ax)...(dx),(ax)正好是结果的低16位
mov cx,dx;结果的余数放入cx
pop dx;取出高16位除后的商(dx),正好是结果的高16位
;公式中需要*65536,为何此处(dx)直接是结果?
pop bx;取出bx原始值
ret
code ends
end start
接着是实验10第1题
;子程序练习
;名称:show_str
;功能:按给定参数输出0结尾的字符串
assume cs:code
data segment
db 'Welcome to masm!',0
data ends
code segment
start: 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 21h
show_str:
push ax
push es
;找偏移 (es):(dh)*160+(dl)*2
mov ax,0b800h
mov es,ax
mov al,160
mul dh ;结果在(ax)
mov bx,ax
mov al,2
mul dl
add bx,ax ;偏移(bx)
;循环读字符并写入
mov ah,cl;先保存颜色属性
xor cx,cx;清空cx
s0: mov cl,ds:;取出data中第si个字符
jcxz ok;(cx)=0如果字符为0跳到ok
mov al,cl;暂存字符
mov es:,ax;此时 (ah)=颜色属性,(al)=字符,将其保存到b800:偏移 中
inc si;下个字符
add bx,2;下个显存位置
jmp short s0
ok: pop es
pop ax
ret
code ends
end start 实验10的第3题,代码越来越长。不知到win32汇编是啥状况。
;名称:dtoc
;功能:将word型数据变为十进制字符串,0结尾
;参数:(ax) = word型数据
; ds:si 串首
assume cs:code
data segment
db 10 dup (0)
data ends
code segment
start: mov ax,12666
mov bx,data
mov ds,bx
mov si,0
call dtoc;调用子程序,将数据变为字符串并保存到指定位置
mov dh,8
mov dl,3
mov cl,2
mov si,0
call show_str;调用输出子程序
mov ax,4c00h
int 21h
dtoc:
push cx
s0: mov cx,ax
jcxz ok1;被除数为0表示循环结束,跳出
mov bx,10;12666/10=1266>256,商要用(ax)保存,所以除数要16位(bx),不能(bl)
xor dx,dx;12666<65536,除数16位,则被除数必须用到(dx),12666<65536,(dx)置0即可
div bx;除后的结果 (ax)...(dx)
push dx;保存余数,并将(ax)作为下次循环的被除数
inc si;记录循环次数,求得字符串长度
jmp short s0
ok1: mov cx,si
xor si,si
s1: pop ds:;依次出栈,将字符串顺序保存到ds:中
mov bl,30h
add ds:,bl;数值转换为对应ASCII码
inc si
loop s1
mov ds:,cx;将0保存到字符串结尾
pop cx
ret
show_str:;输出字符串子程序
push ax
push es
mov ax,0b800h
mov es,ax
mov al,160
mul dh
mov bx,ax
mov al,2
mul dl
add bx,ax
mov ah,cl
xor cx,cx
s2: mov cl,ds:
jcxz ok2
mov al,cl
mov es:,ax
inc si
add bx,2
jmp short s2
ok2: pop es
pop ax
ret
code ends
end start
ret 用栈中数据修改ip 相当于 pop ip
retf 用栈中数据修改cs和ip 相当于 pop cs , pop ip
call 将当前ip 或 cs,ip入栈,然后跳转
1. call 标号 相当于 push ip , jmp near ptr 标号
2. call far ptr 标号 相当于 push ip , jmp far ptr 标号
3. call 16位reg 相当于 push ip , jmp 16位reg
4. call word ptr 内存单元地址 相当于 push ip , jmp word ptr 内存单元地址(2字节)
5. call dword ptr 内存单元地址 相当于 push cs , push ip , jmp dword ptr 内存单元地址(4字节)
页:
[1]