参数:(ax)=word型数据,ds:si指向字符串首地址。
(ax)=12666=317a,要求在屏幕指定位置显示指定颜色的12666字符串。
显示的方法已经在实验10另一个题目写了。关键是317a-->12666。
方法是不停的除以10,保存余数,然后每个余数数字转字符串(+30H)。
因为从低位开始获得余数,所以用stack中转逆序保存到data里。
注意※1处栈的定位代码mov bx,stack和mov ss,bx不能放在dtoc里,原因见下图。
因为call dtoc时使用了一次栈,把ip=000e保存在0769:fffe,
而dtoc ret读取的ip=0000保存在076b:fffe,
debug可以发现这会导致程序从start重新运行一次,第二次运行能拿到正确结果。
但是这种写法无法连续运行代码两次,第二次会卡死。
但如果第一次是debug运行,或者直接运行后重新编译或重新link,
第二次又可以正常运行。原因不明。
如果这两行代码写在main里,程序只会运行一次,且可重复运行。
assume cs:code
data segment
db 10 dup (0)
data ends
stack segment
dw 16 dup(0)
stack ends
code segment
start:
mov ax,12666
mov bx,data
mov ds,bx
mov si,0
mov bx,stack ;//这两行不能放dtoc方法里 ※1
mov ss,bx
call dtoc
mov dh,3
mov dl,4
mov cl,1
call fun
mov ax,4c00h
int 21h
dtoc:
;//mov bx,stack 不能写这里
;//mov ss,bx
mov bx,10
push si ;push 0做标记
s10:
mov dx,0
div bx
mov cx,ax
add dx,30h
push dx
jcxz ok
inc si
jmp short s10
ok:
mov si,0
mov cx,0
s11:
pop cx
jcxz ok1
mov [si],cl
inc si
jmp short s11
ok1:
ret
fun:
mov ax, data ;//这三行以前放在main里,
mov ds, ax ;//这个题没放,所以放到这里
mov si,0 ;//
mov ax,0b800h
mov es,ax
call getColor
push ax
call getRow
push ax
call getCol
push dx
pop ax
pop bx
add bx,ax
pop ax
s2: mov cl,[si]
jcxz ret1
mov es:[bx],cl
mov es:[bx+1],ax
add bx,2
inc si
jmp short s2
ret1:ret
getColor:
mov bl,2
mov ch,0
mov ax,00001000b
s1: div bl
loop s1
ret
getRow:
mov al,dh
mov dh,160
mul dh
ret
getCol:
sub dl,1
add dl,dl
mov dh,0
ret
code ends
end start