1.源代码
数字范围:0~255
xor ax,ax
xor bx,bx
xor cx,cx
xor dx,dx
mov al,163
mov bh,10
s1:div bh
add ah,0x30
mov dl,al
mov al,7
xchg ah,al
push ax
mov al,dl
xor ah,ah
inc cx
cmp al,0
jne s1
mov ax,0xb800
mov es,ax
xor di,di
s2:pop word es:[di]
add di,2
loop s2
jmp $
times 510-($-$$) db 0
db 0x55,0xaa
注:xchg ah,al这一指令非常关键
nasm编译成bin文件,再写入vhd文件,用VirtualBox执行
2.运行效果
3.分析
1.初始的四行用于初始化ax,bx,cx,dx寄存器
xor ax,ax
xor bx,bx
xor cx,cx
xor dx,dx
2.al存储要分解的数字,bh存储div 8位src的除数
mov al,163
mov bh,10
3.div 8位src ,al存储商,ah存储余数,将al+0x30转换为ASCII码,由于之后要将ax入栈,
因此mov dl,al中dl将al的值暂存,再为al赋值7(按8086RGB的规则,为黑底白字)
s1:div bh
add ah,0x30
mov dl,al
mov al,7
4.xchg ah,al是用来交换ah,al寄存器的值(exchange),因为push ax对应的是pop word es:[di],
由栈来看,ax的al要存储字符的ASCII码(余数+30h),ah要存储字符的属性,但div执行后al存储商,ah存储余数,因此需要交换al和ah中的数值,因此使用xchg指令
xchg ah,al
push ax
mov al,dl
xor ah,ah
inc cx
5.ax入栈后,从dl寄存器中恢复al的值,为ah清零,cx+1,记录之后按word出栈的次数
push ax
mov al,dl
xor ah,ah
inc cx
6.比较al是否为0,不为0则继续除10(jne s1)
cmp al,0
jne s1
7.设置es:di指向显存区第0页的第一个字节
mov ax,0xb800
mov es,ax
xor di,di
8.s2循环是为了写入显存区
s2:pop word es:[di]
add di,2
loop s2
9.剩余的三个指令用00来填满主引导扇区,以55 AA结尾
jmp $
times 510-($-$$) db 0
db 0x55,0xaa
标签:汇编,8086,xor,di,ah,mov,al,用栈,ax
From: https://blog.csdn.net/2401_85828611/article/details/143226217