8-div指令和进制转换

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_35733751/article/details/85037871

1. 十进制与N进制之间的转换

在学习计算机基本原理时,大家应当知道,在计算机中最常使用的进制就是二进制,二进制是现代主流电子计算机的基础。并且二进制与我们熟悉的十进制之间有着一对一的关系,比如十进制数5对应的二进制数是101,任何一个十进制数都对应一个二进制数,以及十六进制数,不信你可以自己推导一遍.....

哈哈,开个玩笑,显然是不可能全部都推导一遍的,但我们可以看几个示例。

来看一个十进制数字:356D。

我们从上面这个数字可以知道,数字6在个位上,所以是六个。数字5在十位上,所以是五十。数字3在百位上,所以是三百,于是356D =3 \times 10^{2} + 5 \times 10^{1}+ 6 \times 10^{0}

 

我们再看一个二进制数字:1011B。

1011B=1 \times 2^3 + 0 \times 2^2 + 1 \times 2^1 + 1 \times 2^0

=11D

 

再来看一个十六进制数:125H

125H = 1 \times 16^2 + 2 \times 16^1 + 5 \times 16^0

=293D

 

通过以上这几个数字,我们可以总结一下:把一个N进制数转换成十进制数,只要分解成以上格式求和相加就可以了。

我们已经总结出N进制转十进制的规律,接下来考虑十进制转N进制了,对此我们可以使用求余法。求余法非常简单,只要不停地除以对应的进制基数,直到商为0,然后将每一步得到的余数倒着串起来即可。

 

比如要把26D转换成二进制就除以2,使用求余法如下:

26 / 2 =13  余 0
13 / 2 = 6   余 1
6 / 2 = 3   余 0
3 / 2 = 1 余 1
1 / 2 = 0 余 1

把余数倒着串起来26D=11010B

 

同样的道理,如果要把26D转换成十六进制就除以16,使用求余法如下:

26 / 16 = 1 余 A
1 / 16 = 0 余 1

把余数倒着串起来26D=1AH

 

2. div指令

到目前为止,我们已经学过了三个指令:mov add jmp。

  • mov是一个传送数据的指令
  • add是用于加法运算的指令
  • jmp是用于跳转的指令。

 

现在有这么一个问题:假设寄存器AX里存放一个三位的十进制数123D,那么如何把ax的值输出到屏幕上?

有同学飞快的想到把十进制123的ASCII码查出来,然后从显存的起始地址0xB800开始输出就ok了。虽然这样也可以把123输出到屏幕,但这并不是我们所期望的把寄存器AX的值输出到屏幕。

那到底应该怎么样实现呢?我们可以把AX中的十进制数123进行分解,拿到个位,十位,百位分别对应的ASCll编码,因此需要准备三个字节的内存空间存放AX的百位,十位,个位,给出的代码如下:

mov ax,0xB800
mov es,ax 
mov ax,0x07C0
mov ds,ax
jmp 0x07C0:code 

;存放123的百位,十位,个位
temp:
db 0x00,0x00,0x00 

code:
mov ax,123D

;===================================

mov al,byte [ds:temp+0]   ;存放百位
add al,48		  ;把百位上的数转换成ASCII码值
mov byte[es:0],al	  ;把百位上的数写入到显存
mov byte[es:1],7 

mov al,byte [ds:temp+1]
add al,48
mov byte[es:2],al		    ;存放十位
mov byte[es:3],7 

mov al,byte [ds:temp+2]		;存放个位
add al,48
mov byte[es:4],al
mov byte[es:5],7 

;===================================

end:
jmp 0x07C0:end 

;填充数据
times 510-($-$$) db 0x00
db 0x55,0xAA 

 

上面这个代码还不完整,现在我们还需要拿到十进制数123的百位,十位,个位上的数,而前面我们所学过的汇编指令已经满足不了我们的需求了,现在要学习一个新的指令div指令,div是单词divide的缩写,翻译过来就是除法的意思。

通过div指令和求余法我们就可以分别拿到百位,十位,个位上的数了,如下所示:

123/10 商=12,余数=3
12 /  10  商=1 ,余数=2
1  /  10  商=0 ,余数=1

现在还有一个问题,如何使用div指令?

在8086汇编语言中使用div指令如下图所示:

被除数:默认放在AX或DX中

除数:存放到一个8位的通用寄存器或者内存地址

结果:当div运行完成后,把商放到寄存器AL中(低八位),余数放到寄存器AH中(高八位)。

 

示例汇编代码如下:

mov ax,123D		;除数
mov bl,10D		;被除数
div bl			;相当于ax / bl,结果为:商=al,余数=ah  , ax = al+ah

以上汇编代码相当于:

mov ax,123D		;ax = 123
mov bl,10D		;bl = 10
div bl			;123/10=12...3		al = 12  ah=3  ,al = 0x0c  ah=0x03	,ax = 0x030c

但是ax中的0x030c转换为十进制的话是780,因此,我们需要通过mov指令把ah寄存器的值改为0,那么寄存器ax中的值就为0x000c了,十进制为12,这一步就拿到了除数。

 

最终的代码:

                              ;文件名:  002.asm
                              ;说明:    把寄存器AX中的值显示到屏幕                        
                                                            

mov ax,0xB800
mov es,ax 
mov ax,0x07C0
mov ds,ax
jmp 0x07C0:code 
;  百位,十位,个位
temp:
db 0x00,0x00,0x00

code:
mov ax,123	;被除数
mov bl,10D	;除数
div bl		;相当于123/10=12...3	结果:al = 12 , ah=3

mov byte[ds:temp+2],ah	;存放个位

mov ah,0x00		;把ah改为0
div bl
mov byte[ds:temp+1],ah	;存放十位

mov ah,0x00
div bl
mov byte[ds:temp+0],ah	;存放百位

;===================================

mov al,byte [ds:temp+0]		
add al,48			    	;把百位上的数字转换为ASCII码值	
mov byte[es:0],al			;把AX中的低八位写到显存中
mov byte[es:1],7			;颜色显示为黑底白字

mov al,byte [ds:temp+1]		;同上
add al,48
mov byte[es:2],al
mov byte[es:3],7

mov al,byte [ds:temp+2]		;同上
add al,48
mov byte[es:4],al
mov byte[es:5],7

;===================================

end:
jmp 0x07C0:end

times 510-($-$$) db 0x00
db 0x55,0xAA 

 

编译程序写入到0扇区,再调试运行程序:

猜你喜欢

转载自blog.csdn.net/qq_35733751/article/details/85037871
今日推荐