其他两个子程序:
1.编写子程序-显示字符串 https://blog.csdn.net/qq_41700629/article/details/89426234
2.编写子程序-解决除法溢出的问题 https://blog.csdn.net/qq_41700629/article/details/89426260
3.编写子程序-数值显示
把123,12666,1,8,3,38以十进制的形式显示在屏幕的八行三列,用绿色显示出来,可调用第一个子程序show_str
程序如下:
assume cs:code
data segment
dw 123,12666,1,8,3,38
data ends
stack segment
dw 21 dup(0)
stack ends
code segment
start: mov ax,stack
mov ss,ax
mov sp,2ah ;设置栈
mov ax,data
mov ds,ax
mov si,10 ;ds:[si]最后一个数据,步长是2
;mov di,
mov ax,0h
push ax ;先压栈0,作为显示的结束标志
mov cx,6h ;六个数字
s: mov es,cx ;用es保存cx
mov ax,ds:[si]
mov dx,0h ;将数据放入被除数低16位寄存器ax中,并将高16位置0
mov bl,0ah
mov bh,0h ;bx存放除数10
mov cx,ax ;循环条件
s1: div bx
add dl,30h
push dx ;余数低8位压栈
mov dx,0h ;高16位重置0
mov cx,ax
inc cx
loop s1 ;一个数除到0则结束
mov ax,0020H
push ax ;一个数完了空一格
sub si,2 ;指向上一个数字
mov cx,es ;恢复cx
loop s
call show_str
mov ax,4c00h
int 21h
show_str:
mov dh,8
mov dl,3
mov cl,2
mov ax,stack
mov ds,ax
mov si,sp ;数据地址已修改为与本程序相符,即栈顶
add si,2 ;由于最后还空了一格,此处加2
mov ax,0b800h
mov es,ax ;显存段地址es
mov al,0a0h
mov bh,6h
mul bh ;第七行偏移地址放在ax中
mov di,4h
add di,ax ;第3列地址放在di中,不再使用ax,用es:[di]
mov al,cl ;把颜色从cl放到al中
mov ch,0
f: mov cl,ds:[si]
jcxz ok ;检测是否放到0
mov es:[di],cl ;放字母
inc di
mov es:[di],al ;放颜色
inc di
add si,2
jmp short f
ok: ret
code ends
end start
结果图:
问题:
- 在复制过来子程序show_str的时候还对其中好多数据进行了修改,说明子程序写的复用性不太高,应该改进,
- 还有就是写完程序发现虽然可以显示,但陷入了死循环,是因为在子程序中add sp,2私自修改了sp导致ret返回错了地方
- 使用call ret指令的时候,由于压栈ip保存返回地址,所以在程序开头设置栈空间的时候就要预留一个ip的空间