【8086汇编】用栈来分解并显示数字

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执行

点我下载编译后的bin文件

2.运行效果

51a7d56b3dd848e5b755014f2216d479.png

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指令

扫描二维码关注公众号,回复: 17421720 查看本文章
   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    

猜你喜欢

转载自blog.csdn.net/2401_85828611/article/details/143226217