题目中要求显示一段数字,但是我发现很多博主都以课本中的案例显示12666,但是王爽的目的是想让大家使用汇编显示如下的数字 123,12666,1,8,3,38
我这里总结了比较简单逻辑清晰的代码,供大家参考
assume cs:code,ds:data,ss:stack
data segment
dw 123,12666,1,8,3,38
db 4 dup (0)
db 64 dup (0) ;用来存放将数字一个一个拆解之后的数字
;和对应数字的ASCII码
data ends
stack segment
db 32 dup (0) ;设置足够大的数据用来存放数据
stack ends
code segment
start:
mov ax,data
mov ds,ax
mov bx,0 ;bx用来定位data段的偏移地址
mov ax,stack
mov ss,ax
mov sp,32 ;sp设置栈指针指向栈顶
mov di,0
call dtoc ;dtoc 子程序实现word(字型)数据转换为
;表示十进制数的字符串,字符串以0为结尾符。
mov dh,8 ;屏幕显示的行号
mov dl,3 ;屏幕显示的列号
mov cl,2 ;屏幕显示的内容颜色属性
call show_str
mov ax,4c00h
int 21h
dtoc: push ax
push bx
push cx
push dx
push si
push di
s1: mov cx,[bx] ;取在data段中的数据,如果为0则跳出
jcxz ko1
mov si,0 ;计数器,用来计算入栈次数
mov ax,[bx] ;ax用来动态存放data段中的各个数据进行拆分运算
s2: mov cx,10
mov dx,0 ; 16位相除,被除数为32位
div cx ;运行指令商在dx中,当这个数字一直除以10
;得到一个商为0则表示该数除完了
mov cx,ax ;当商为0则代表数拆完了
jcxz intack
add dx,30h ;如果不是0,则代表该数字未拆完,将余数加上30H得到相应的ASCII码
push dx ;入栈保护,也是为了之后出栈倒置数据跟原来的一样。
inc si
jmp short s2
intack: add dx,30h
push dx
inc si
mov cx,si ;进行si次出栈
s3: pop ax
mov ds:10h[di],al
inc di
loop s3
mov ah,20h ;20h 代表空格的ASCII码
mov ds:10h[di],ah ;在每一个数字后面加上空格
inc di ;指向下一个内存
add bx,2
jmp short s1
ko1:pop di
pop si
pop dx
pop cx
pop bx
pop ax
ret
show_str:
push cx
push si
mov ax,0b800h
mov es,ax ;屏幕的段地址给到es
mov al,160
dec dh ;dh减1
mul dh
mov bp,ax ;将ax保存到bp中,因为下面还需要用到
mov al,2
mul dl
sub ax,2
add bp,ax ;bp就是屏幕的起始的偏移地址
mov di,0 ;屏幕输出的偏移
mov al,cl ;将颜色使用al保存
mov ch,0
s: mov cl,10h[bx]
jcxz s0
mov es:[bp+di],cl ;屏幕数据
mov es:[bp+di+1],al ;屏幕数据属性
inc bx
add di,2
jmp short s
s0: pop si
pop cx
ret
code ends
end start
debug 的结果如下图: