在网上搜了下,发现对于实验十的第三个几乎没有全过程的代码,只有输出一个12666的例子的实现,调试了一晚上,终于成功输出,直接上代码。其中的注释是在调试过程中加上的,有看不明白的地方可以评论问我,会及时回答。
assume cs:code,ds:data,ss:stack
data segment
dw 123,12666,1,8,3,38
db 20 dup (0) ;存转换好的字符串
data ends
stack segment
dw 16 dup (0)
stack ends
code segment
start:
mov ax,data
mov ds,ax
mov ax,stack
mov ss,ax
mov sp,16
mov si,0 ;传数字类型首地址给itos
call itos ;call要压ip的,会用到栈
mov si,12 ;传存字符串的首地址给show ptr
mov cl,3
mov dh,8
mov dl,3
call show_str
mov ax,4c00h
int 21h
itos:
mov bx,10
mov cx,6
mov bp,0
getnum:
mov ax,[si] ;get a number to ax
mov di,0 ;统计字符串多长,循环多少次
push cx
;mov ch,0
mov dx,0 ;还是要32/16否则12666会溢出
divi:
div bx
mov cx,ax
add dx,30h
push dx
mov dx,0 ;只留商,dx余数清0
inc di
jcxz pops ;商为0则除法可停
;mov ah,0 ;余数清0,只留下上次运算的商
jmp short divi
pops:
mov cx,di
s:
pop ax
mov ds:12[bp],al ;卧槽,bp默认用栈段???
inc bp
loop s
mov byte ptr ds:12[bp],0
inc bp
pop cx
add si,2
loop getnum
ret
show_str:
mov ax,0b800h
mov es,ax
mov al,160 ;占两个字节
mul dh
mov dh,0
dec dl ;列从1索引,要注意
add dx,dx ;占两个字节
add ax,dx ;现在ax存的是字符串在es中开始写入的首地址了
mov bx,ax
mov al,cl ;现在al存颜色了
mov cx,6
jmp short write
write:
push cx
s1:
mov ch,0
mov cl,[si]
jcxz loops
mov es:[bx],cl
mov es:1[bx],al
add bx,2
inc si
jmp short s1
loops:
mov byte ptr es:[bx],32 ;如果是0则写入一个黑底的空格
mov es:1[bx],al
pop cx
add bx,2
inc si
loop write
ret
code ends
end start