实验10 三题 对跳转指令的巩固
显示字符串
解决除法溢出
数值显示
显示字符串
题目要求
题目分析
把实验9中代码改为一个接口
行对应地址为 行数 X A0
列对应地址为 (列数 X 2) H
代码
assume cs:code, ds:data
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:
mov ax,0b800h
mov es,ax
mov bh,dh
mov bl,dl
mov ax,0a0h
mul bh
mov si,ax ;行
mov ax,2
mul bl
mov di,ax ;列
add si,di
mov bx,si
mov si,0
mov di,0
s:
push cx
mov cl,ds:[si]
jcxz ok
mov al,ds:[si] ;字符及属性
pop cx
mov ah,cl
mov es:[bx+di],ax
inc si
add di,2
jmp short s
ok:
pop cx
ret
code ends
end start
结果
问题
题目用dx存储行列信息 但是再运算乘法的时候,dx被默认存储结果高位
所以要注意dx先赋值 再运算
cx规定存储字体属性信息 由于目前学到的内容只能用jcxz来判断最后一位是否为0
所以要用栈控制cx的值
解决除法溢出
题目要求
题目分析
根据题目给出的提示运算1000000/10 即F4240H/AH
高位为dx = fh 低位ax = 4240h
除数cx = a
X/N = int(dx/cx) * 10000h+[rem(dx/cx) * 10000h+ax]/cx
代入可得答案
32位除法被分解为16位的除 乘 除 乘 加 除 加
其中第一三步为同一操作的不同结果 写在一个段里即可
注意到乘10000H时 低位恒等于0 高位恒等于被乘数 所以ax dx均不需要入栈操作
在运算乘除时需要用到ax与整体上的ax冲突
所以需要用到栈
代码
为了方便分析 注释由题目数据给出
测试数据为987654321/15056
结果为1003E…2A51
assume cs:codesg,ss:stack
stack segment
dw 8 dup(0)
stack ends
codesg segment
start:
mov ax,stack
mov ss,ax
mov sp,16
mov ax,68b1h
mov dx,3adeh
mov cx,0ffffh
call divdw ;第一个入栈的是ip
mov ax,4c00h
int 21h
divdw:
push ax
mov ax,dx
mov dx,0
div cx ;/ ax为X/N的商1 dx为余数5
mov bx,ax ;商高位
pop ax
div cx
mov cx,dx
mov dx,bx
ret
codesg ends
end start
结果
问题
第一个入栈的是call执行后的ip
汇编中如2/3 ax为0 dx为2
这就导致当字型数据高位>除数时 得不到正确结果
数值显示
题目要求
题目分析
根据题目所给提示
1.用求余方法确定每位值
2.加上30H位对应ascii码
3.JCXZ判断
代码
assume cs:codesg,ds:datasg
datasg segment
db 10 dup(0)
datasg ends
codesg segment
start:
mov ax,12666
mov bx,datasg
mov ds,bx
mov si,0
call dtoc
mov dh,8
mov dl,3
mov cl,2
call show_str
mov ax,4c00h
int 21h
dtoc:
mov dx,0 ;初始化
mov bx,0ah
div bx
add dx,30h
mov ds:[si],dl
mov dx,0
inc si
mov cx,ax
jcxz finsh
jmp short dtoc
finsh:
mov dx,si
mov cx,dx
mov si,0
s1:
mov bl,ds:[si] ;栈一次传一个字节
push bx
inc si
loop s1
mov cx,dx
mov si,0
s2:
pop ds:[si]
inc si
loop s2
ret
show_str:
mov ax,0b800h
mov es,ax
mov bh,dh
mov bl,dl
mov ax,0a0h
mul bh
mov si,ax ;行
mov ax,2
mul bl
mov di,ax ;列
add si,di
mov bx,si
mov si,0
mov di,0
s:
push cx
mov cl,ds:[si]
jcxz ok
mov al,ds:[si] ;字符及属性
pop cx
mov ah,cl
mov es:[bx+di],ax
inc si
add di,2
jmp short s
ok:
pop cx
ret
codesg ends
end start
结果
问题
算每位值的时候存储顺序是逆的 要用栈排正
用栈传递字节的时候还是只赋值低位比较好,这样看的也比较清晰
dtoc中用了除法 但是在主代码段中没有给dx赋值,导致debug正常 运行出错
在编写程序时要检查寄存器的初始化
来源:CSDN
作者:四位
链接:https://blog.csdn.net/qq_44803739/article/details/104093837