汇编语言练习_1_数字分解_显示

本文介绍了一段使用汇编语言编写的BIOS程序,该程序通过Bochs虚拟机和VirtualBox工具进行调试和运行。程序将122、45536和195535这三个数字分解并转换为ASCII码,然后输出到屏幕上。通过循环和除法指令实现了数字的分解,最后将结果以逆序的方式填充到显存中。解析了代码中的关键步骤,包括数据段设置、字符串长度计算、内存布局以及屏幕显示的字符填充等。
摘要由CSDN通过智能技术生成

环境

1、Bochs虚拟机

代码调试

2、VirtualBox

BIOS运行

工具

1、notepad++

编写代码

2、nasm

编译工具

思路

第一步:

定义将要输出的十进制数据

第二步:

创建存储分解位数的空间,并填入-16,后面-16在输出到显存上的时候会加上0x30,变为空格所对应的ASCII码

此时实际内存情况:

第三步:

对122进行分解,并将分解结果存储到第二步创建的空间

此时实际内存情况:

第四步:

对45536进行分解,并将分解结果存储到第二步创建的空间

此时实际内存情况:

第五步:

对195535进行分解,并将分解结果存储到第二步创建的空间

此时实际内存情况:

第六步:

将分解结果输出到显存上,输出到显存的代码解析

此时实际显存情况:

前4行就是我们输出到显存上的数据
举例说明:
0x31就是十进制的48,48作为ASCII码对应的字符就是1,0x07就是它的属性(前后背景及其颜色)
0x39就是十进制的56,56作为ASCII码对应的字符就是9,0x07就是它的属性(前后背景及其颜色)

屏幕输出:

……

第七步:

$获取当前偏移地址,jmp指令跳转至当前偏移地址,形成死循环

解析

1、第二行中jmp code

是为了跳过数据段,执行代码

2、计算字符串长度

标号data_res与标号code表示偏移,所以相减能够得到字符串长度

3、ds为何为0x07c0

因为BIOS程序会被加载到0x0000 : 0x7c00,所以该程序的起始段地址就是0x07c0

5、loop s解释

loop与cx配合能够起到for循环的效果
当cx不为零,程序跳转至s执行
当cx为零时,则按照顺序执行

6、第111行加上0x30的原因

第二步创建的空间存储的是一个个数字,需要转换为其对应的ASCII码,加上0x30,就能进行转换

7、除法指令解析

链接

8、数字分解原理

122 / 10 =12…2
12 / 10 = 1…2
1 /10 =0…1

9、为何屏幕显示的数字是逆序的

实际内存:

数字分解时是逆序分解,各个数字填入第二步创建的空间时,应该是221 63554 535591
为了正常看到数字,我在输出到显存的时候是倒着输出的
就变成了 195535 45536 122
但是也可以将它们按照正常的顺序输出到显存,不过取数据的时候就得跳来跳去的取数据,索性就倒着输出

10、结尾的字符填充

我写的是BIOS程序,计算机对BIOS程序的要求就是512字节,且以0x55,0xAA结尾

效果

1、要求


将数字122,45536,195535输出到屏幕上

2、virtualbox

3、bochs

代码

1、汇编代码

start:
	jmp code
	
data: db 122          ;1byte
	  dw 45536        ;2byte
	  dd 195535        ;4byte
data_res:  
	  db 0,0,0,-16
	  db 0,0,0,0,0,-16
	  db 0,0,0,0,0,0

code:
	;指向数据地址 ds:si
	mov ax,0x07c0
	mov ds,ax
	mov si,data
	
	;指向存储数据地址 es:di
	mov es,ax
	mov di,data_res
	
	;分解开始:16位除法 ax存被除数,bl存除数,al存商,ah存余
	;被除数设置
	xor ax,ax
	mov al,[ds:si]
	inc si
	
	;除数设置
	xor bx,bx
	mov bl,10
	
	mov cx,3
l0:
	;结果计算
	div bl
	mov [es:di],ah
	inc di
	xor ah,ah
	loop l0
	
	inc di;留给空格
	
	;分解开始:32位除法 ax存被除数低2字节,dx存被除数高2字节,bx存除数,ax存商,dx存余
	;被除数设置
	xor ax,ax
	xor dx,dx
	mov ax,[ds:si]
	inc si
	inc si
	
	;除数设置
	xor bx,bx
	mov bl,10
	
	mov cx,5
l1:
	;结果计算
	div bx
	mov [es:di],dl
	inc di
	xor dx,dx
	loop l1
	
	inc di;留给空格
	
	;分解开始:32位除法 ax存被除数低2字节,dx存被除数高2字节,bx存除数,ax存商,dx存余
	;被除数设置
	xor ax,ax
	xor dx,dx
	mov ax,[ds:si]
	inc si
	inc si
	mov dx,[ds:si]
	inc si
	inc si
	
	;除数设置
	xor bx,bx
	mov bl,10
	
	mov cx,6
l2:
	;结果计算
	div bx
	mov [es:di],dl
	inc di
	xor dx,dx
	loop l2
	
	
code1:
	;es指向显存,di做指针
	mov ax,0xB800
	mov es,ax
	mov di,0x0
	
	;ds指向待写入数据,si做指针
	mov ax,0x07c0
	mov ds,ax
	mov ax,code
	mov si,ax
	
	;循环计数器
	mov cx,code-data_res

l3:
	;写显存
	;al做中转站
	dec si
	mov al,[ds:si]
	add al,0x30;数字转字符串
	mov byte [es:di],al
	
	inc di
	mov byte [es:di],0x07
	
	inc di
	loop l3
	
	jmp $
current:
	times (510-(current-start)) db 0
	db 0x55,0xAA

2、机器码 对照 汇编代码

     1                                  start:
     2 00000000 EB17                    	jmp code
     3                                  	
     4 00000002 7A                      data: db 122          ;1byte
     5 00000003 E0B1                    	  dw 45536        ;2byte
     6 00000005 CFFB0200                	  dd 195535        ;4byte
     7                                  data_res:  
     8 00000009 000000F0                	  db 0,0,0,-16
     9 0000000D 0000000000F0            	  db 0,0,0,0,0,-16
    10 00000013 000000000000            	  db 0,0,0,0,0,0
    11                                  
    12                                  code:
    13                                  	;指向数据地址 ds:si
    14 00000019 B8C007                  	mov ax,0x07c0
    15 0000001C 8ED8                    	mov ds,ax
    16 0000001E BE[0200]                	mov si,data
    17                                  	
    18                                  	;指向存储数据地址 es:di
    19 00000021 8EC0                    	mov es,ax
    20 00000023 BF[0900]                	mov di,data_res
    21                                  	
    22                                  	;分解开始:16位除法 ax存被除数,bl存除数,al存商,ah存余
    23                                  	;被除数设置
    24 00000026 31C0                    	xor ax,ax
    25 00000028 3E8A04                  	mov al,[ds:si]
    26 0000002B 46                      	inc si
    27                                  	
    28                                  	;除数设置
    29 0000002C 31DB                    	xor bx,bx
    30 0000002E B30A                    	mov bl,10
    31                                  	
    32 00000030 B90300                  	mov cx,3
    33                                  l0:
    34                                  	;结果计算
    35 00000033 F6F3                    	div bl
    36 00000035 268825                  	mov [es:di],ah
    37 00000038 47                      	inc di
    38 00000039 30E4                    	xor ah,ah
    39 0000003B E2F6                    	loop l0
    40                                  	
    41 0000003D 47                      	inc di;留给空格
    42                                  	
    43                                  	;分解开始:32位除法 ax存被除数低2字节,dx存被除数高2字节,bx存除数,ax存商,dx存余
    44                                  	;被除数设置
    45 0000003E 31C0                    	xor ax,ax
    46 00000040 31D2                    	xor dx,dx
    47 00000042 3E8B04                  	mov ax,[ds:si]
    48 00000045 46                      	inc si
    49 00000046 46                      	inc si
    50                                  	
    51                                  	;除数设置
    52 00000047 31DB                    	xor bx,bx
    53 00000049 B30A                    	mov bl,10
    54                                  	
    55 0000004B B90500                  	mov cx,5
    56                                  l1:
    57                                  	;结果计算
    58 0000004E F7F3                    	div bx
    59 00000050 268815                  	mov [es:di],dl
    60 00000053 47                      	inc di
    61 00000054 31D2                    	xor dx,dx
    62 00000056 E2F6                    	loop l1
    63                                  	
    64 00000058 47                      	inc di;留给空格
    65                                  	
    66                                  	;分解开始:32位除法 ax存被除数低2字节,dx存被除数高2字节,bx存除数,ax存商,dx存余
    67                                  	;被除数设置
    68 00000059 31C0                    	xor ax,ax
    69 0000005B 31D2                    	xor dx,dx
    70 0000005D 3E8B04                  	mov ax,[ds:si]
    71 00000060 46                      	inc si
    72 00000061 46                      	inc si
    73 00000062 3E8B14                  	mov dx,[ds:si]
    74 00000065 46                      	inc si
    75 00000066 46                      	inc si
    76                                  	
    77                                  	;除数设置
    78 00000067 31DB                    	xor bx,bx
    79 00000069 B30A                    	mov bl,10
    80                                  	
    81 0000006B B90600                  	mov cx,6
    82                                  l2:
    83                                  	;结果计算
    84 0000006E F7F3                    	div bx
    85 00000070 268815                  	mov [es:di],dl
    86 00000073 47                      	inc di
    87 00000074 31D2                    	xor dx,dx
    88 00000076 E2F6                    	loop l2
    89                                  	
    90                                  	
    91                                  code1:
    92                                  	;es指向显存,di做指针
    93 00000078 B800B8                  	mov ax,0xB800
    94 0000007B 8EC0                    	mov es,ax
    95 0000007D BF0000                  	mov di,0x0
    96                                  	
    97                                  	;ds指向待写入数据,si做指针
    98 00000080 B8C007                  	mov ax,0x07c0
    99 00000083 8ED8                    	mov ds,ax
   100 00000085 B8[1900]                	mov ax,code
   101 00000088 89C6                    	mov si,ax
   102                                  	
   103                                  	;循环计数器
   104 0000008A B91000                  	mov cx,code-data_res
   105                                  
   106                                  l3:
   107                                  	;写显存
   108                                  	;al做中转站
   109 0000008D 4E                      	dec si
   110 0000008E 3E8A04                  	mov al,[ds:si]
   111 00000091 0430                    	add al,0x30;数字转字符串
   112 00000093 268805                  	mov byte [es:di],al
   113                                  	
   114 00000096 47                      	inc di
   115 00000097 26C60507                	mov byte [es:di],0x07
   116                                  	
   117 0000009B 47                      	inc di
   118 0000009C E2EF                    	loop l3
   119                                  	
   120 0000009E EBFE                    	jmp $
   121                                  current:
   122 000000A0 00<rep 15Eh>            	times (510-(current-start)) db 0
   123 000001FE 55AA                    	db 0x55,0xAA

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值