十六進制
十六進制(英文名稱:Hexadecimal),是計算機中數(shù)據(jù)的一種表示方法。同我們?nèi)粘I钪械谋硎痉ú灰粯?。它?-9,A-F組成,字母不區(qū)分大小寫。與10進制的對應關系是:0-9對應0-9;A-F對應10-15;N進制的數(shù)可以用0~(N-1)的數(shù)表示,超過9的用字母A-F。
1、BCD碼與十進制數(shù)的轉(zhuǎn)換
BCD碼與十進制數(shù)的轉(zhuǎn)換關系很直觀,相互轉(zhuǎn)換也很簡單,將十進制數(shù)75.4轉(zhuǎn)換為BCD碼:7-》0111,5-》0101,4-》0100所以拼成8421BCD碼的結(jié)果是:(0111 0101.0100)BCD;若將BCD碼1000 0101.0101轉(zhuǎn)換為十進制數(shù):1000-》8,0101-》5,0101-》5所以結(jié)果是:(85.5)D。
注意:同一個8位二進制代碼表示的數(shù),當認為它表示的是二進制數(shù)和認為它表示的是二進制編碼的十進制數(shù)時,數(shù)值是不相同的。
例如:00011000,當把它視為二進制數(shù)時,其值為24;但作為2位BCD碼時, 其值為18。
又例如00011100,如將其視為二進制數(shù),其值為28,但不能當成BCD碼,因為在8421BCD碼中,它是個非法編碼 。
2、BCD碼的格式
計算機中的BCD碼,經(jīng)常使用的有兩種格式,即分離BCD碼,組合BCD碼。
所謂分離BCD碼,即用一個字節(jié)的低四位編碼表示十進制數(shù)的一位,例如數(shù)82的存放格式為:
_ _ _1 0 0 0 _ _ _ _0 0 1 0 其中_表示無關值。
組合BCD碼,是將兩位十進制數(shù),存放在一個字節(jié)中,例82的存放格式是1000 0010
3、BCD碼的加減運算
由于編碼是將每個十進制數(shù)用一組4位二進制數(shù)來表示,因此,若將這種BCD碼直接交計算機去運算,由于
計算機總是把數(shù)當作二進制數(shù)來運算,所以結(jié)果可能會出錯。例:用BCD碼求38+49。
解決的辦法是對二進制加法運算的結(jié)果采用“加6修正,這種修正稱為BCD調(diào)整。即將二進制加法運算的結(jié)果修正為BCD碼加法運算的結(jié)果,兩個兩位BCD數(shù)相加時,對二進制加法運算結(jié)果采用修正規(guī)則進行修正。修正規(guī)則:
(1)如果任何兩個對應位BCD數(shù)相加的結(jié)果向高一位無進位,若得到的結(jié)果小于或等于9,則該位不需修正;若得到的結(jié)果大于9且小于16時,該位進行加6修正。
(2)如果任何兩個對應位BCD數(shù)相加的結(jié)果向高一位有進位時(即結(jié)果大于或等于16,注意不是修正時的進位),該位進行加6修正。
(3)低位修正結(jié)果使高位大于9時,高位進行加6修正。
下面通過例題驗證上述規(guī)則的正確性。
a)用BCD碼求35+21
35-》 0011 0101+
21-》 0010 0001=
0101 0110-》56
注意:0101+0001并沒有滿足上述3條規(guī)則,同時0011+0010也沒有滿足上述3條規(guī)則,所以結(jié)果不作處理。
b)BCD碼求25+37
25-》0010 0101+
37-》0011 0111=
0101 1100+(低位0101+0111=1100-》12》9所以需要調(diào)整)
06-》 0110=
0110 0010-》62
注意:在給低位加0110調(diào)整時也有向高位進位發(fā)生,但是這是在調(diào)整時的進位,故不做處理。
c)用BCD碼求38+49
38-》0011 1000+
49-》01001001=
1000 0001+(低位1000+1001相加時有進位發(fā)生,所以需要給低位加0110-》調(diào)整)
06-》 0110=
10000111-》87
注意調(diào)整后的結(jié)果也不滿足上述(3)的條件所以不再調(diào)整
d)用BCD碼求42+95
42-》0100 0010+
95-》1001 0101=
11010111-》13 7+(1101是一個非法8421BCD碼,事時上0100+1001相加滿足(1)條件)
06-》0110(注意是給1001+0100加0110調(diào)整)
00010011 0111-》1 3 7
注意結(jié)果不滿足(3)條件所以不再調(diào)整。
c)用BCD碼求91+83
91-》1001 0001+
83-》1000 0011=
00010001 0100 +(1001+1000有進位發(fā)生所以需要給1001+1000相加結(jié)果0001+0110調(diào)整)
06-》0110 =
00010111 0100-》174
注意結(jié)果不滿足(3)條件所以不再調(diào)整。
d)用BCD碼求94+7
94-》1001 0100+
07-》0000 0111=
10011011+(由于結(jié)果的兩位編碼數(shù)滿足上述條件1所以需要給0100+0111+0110調(diào)整)
06-》0110=
1010 0001+(由于結(jié)果的高位1010-》10》9所以滿足上述(3)條件給高位加0110調(diào)整)
06-》0110 =
0001 0000 0001-》101
注意:對于調(diào)整我們只需要關心結(jié)果是不是滿足上述(3)條件,不滿足不予調(diào)整。
e)用BCD碼求76+45
76-》0111 0110+
45-》0100 0101=
1011 1011+(注意這里0101+1011和0111+0100都滿足上述(1)條件所以需要都調(diào)整)
06-》01100110=
000100100001-》121
注意結(jié)果滿足上述(3)條件所以不再調(diào)整。(例子補充于2015-1-11)
兩個組合BCD碼進行減法運算時,當?shù)臀幌蚋呶挥薪栉粫r,由于”借一作十六“與”借一作十“的差別,將比正確的結(jié)果多6,所以有借位時,可采用”減6修正法“來修正。兩個BCD碼進行加減時,先按二進制加減指令進行運算,再對結(jié)果用BCD調(diào)整指令進行調(diào)整,就可得到正確的十進制運算結(jié)果。 實際上,計算機中既有組合BCD數(shù)的調(diào)整指令,也有分離BCD數(shù)的調(diào)整指令。另外,BCD碼的加減運算,也可以在運算前由程序先變換成二進制數(shù),然后由計算機對二進制數(shù)運算處理,運算以后再將二進制數(shù)結(jié)果由程序轉(zhuǎn)換為BCD碼。
16進制數(shù)轉(zhuǎn)換成8421BCD編碼函數(shù)
.INCLUDE hardware.inc
.IRAM
_Led_Out:
.dw 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
_List_8421_Data: //16進位數(shù)轉(zhuǎn)換成8421碼的位權表,萬位每千位進位,千位每百位進位,百位每十位進位
.dw 0xFFFF,0xEA60,0xC350,0x9C40,0x7530,0x4E20,0x2710
//60000-10000
.dw 0x2328,0x1F40,0x1B58,0x1770,0x1388,0x0FA0,0x0BB8,0x07D0,0x03E8
//9000-1000
.dw 0x0384,0x0320,0x02BC,0x0258,0x01F4,0x0190,0x012C,0x00C8,0x0064
//900-100
.dw 0x005A,0x0050,0x0046,0x003C,0x0032,0x0028,0x001E,0x0014,0x000A
//90-10
//.RAM
//.DATA
.code
//=========================================================================================
//函數(shù): hex_to_8421()
//語法:hex_to_8421(被轉(zhuǎn)換數(shù),符號標記)
//描述:16進位數(shù)轉(zhuǎn)換成8421碼,存放在C段中定義好的數(shù)組當中
//須定義一個下標8位的整數(shù)數(shù)組,C段中如下書寫
//extern int led_out [8]={0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0};
//參數(shù):被轉(zhuǎn)換數(shù)小于0xFFFF的數(shù),符號標記0或非零的數(shù)
//返回:無
//=============================================================================================
.PUBLIC _hex_to_8421;
_hex_to_8421: .PROC
push bp to [sp];
bp=sp+1; //基址重定位,準備取參數(shù)
r1=[bp+3]; //備轉(zhuǎn)換成8421碼的16進位數(shù)字
r3=[bp+4]; //符號位標志,為0,則做無符號整數(shù)處理,非1做有符號數(shù)處理
R4=_Led_Out; //輸出數(shù)據(jù)的地址******************************可修改輸出名稱
bp=_List_8421_Data; //基址定位到位權表頭**************************對應.IRAM段,可修改輸入名稱
//------------------------------------------
test R3,0xFFFF; //檢查R3是否非0,如果非零,做有符號數(shù)處理,如果為0,做無符號數(shù)處理
je _hex_loop0; //為0,做無符號數(shù)處理,跳到_hex_loop0
R3=0xF000; //非0,做有符號數(shù)處理
[R4]=r3; //表的第1個單元高4字節(jié)存放符號標記,F(xiàn)為負,0為正
R1-=0X0001; //包括下1步,減1后反碼轉(zhuǎn)換成10進位正數(shù)
R1^=0xFFFF;
_hex_loop0:
R2=0X0007; //R2為進位標志,從9到1循環(huán),R2初置7,進入循環(huán)后減1為6做初值
//------------------------------------------
_hex_loop1: //位權表遍歷開始標記
CALL _Clear_WatchDog; // 清看門狗
BP+=0X0001; //基址加1,定位到位權表第一個有效數(shù)字
R2-=0X0001; //位權減1,準備輸出位權表第一個有效數(shù)字所對應的位數(shù)字
cmp r1,[bp]; //比較被轉(zhuǎn)換數(shù)和當前位權的大小
jb _hex_loop2; //如果被轉(zhuǎn)換數(shù)小于當前位權,則跳到“_hex_loop1”,繼續(xù)比較
jmp _hex_loop3; //如果被轉(zhuǎn)換數(shù)大于當前位權,則跳到“_hex_loop3”,進行轉(zhuǎn)換
_hex_loop2: //R2進位循環(huán)處理的標記
CMP R2,0X0002;
JB _hex_loop4; //包括上1步,如果R2小于2,跳到_hex_loop4,將R2置為10
JMP _hex_loop1; //如果R2大于等于2,跳到“_hex_loop1”,繼續(xù)比較
_hex_loop4:
R2=0x000A; //包括下1步,將R2置為10,跳到“_hex_loop1”,繼續(xù)比較
JMP _hex_loop1;
//------------------------------------------
_hex_loop3: //判斷并輸出數(shù)據(jù)的標記
cmp r1,0x2710;
jnb _hex_2710; //包括上1步,如果R1大于等于0x2710(10000),跳到_hex_2710處理
cmp r1,0x03e8;
jnb _hex_03e8; //包括上1步,如果R1大于等于0x03E8(1000),跳到_hex_03E8處理
cmp r1,0x0064;
jnb _hex_0064; //包括上1步,如果R1大于等于0x0064(100),跳到_hex_0064處理
cmp r1,0x000a;
jnb _hex_000a; //包括上1步,如果R1大于等于0x000A(10),跳到_hex_000A處理
//------------------------------------------
R3=R4+5; //包括下2步,輸出10進制第1位,跳到“_hex_000”,結(jié)束轉(zhuǎn)換
[R3]=R1;
jmp _hex_over;
_hex_2710:
R3=R4+1; //包括下3步,輸出10進制第5位,被轉(zhuǎn)換數(shù)減位權,做被轉(zhuǎn)換數(shù),跳到“_hex_loop1”,繼續(xù)比較
[R3]=R2;
r1-=[bp];
jmp _hex_loop1;
_hex_03e8:
R3=R4+2; //包括下3步,輸出10進制第4位,被轉(zhuǎn)換數(shù)減位權,做被轉(zhuǎn)換數(shù),跳到“_hex_loop1”,繼續(xù)比較
[R3]=R2;
r1-=[bp];
jmp _hex_loop1;
_hex_0064:
R3=R4+3; //包括下3步,輸出10進制第3位,被轉(zhuǎn)換數(shù)減位權,做被轉(zhuǎn)換數(shù),跳到“_hex_loop1”,繼續(xù)比較
[R3]=R2;
r1-=[bp];
jmp _hex_loop1;
_hex_000a:
R3=R4+4; //包括下3步,輸出10進制第2位,被轉(zhuǎn)換數(shù)減位權,做被轉(zhuǎn)換數(shù),跳到“_hex_loop1”,繼續(xù)比較
[R3]=R2;
r1-=[bp];
jmp _hex_loop1;
_hex_over:
pop bp from [sp];
RETF
.ENDP;
.PUBLIC _Clear_WatchDog;
_Clear_WatchDog: .PROC
PUSH R1 TO [SP];
R1 = 0x0001;
[ASM_Port_Watchdog_Clear] = R1;
POP R1 FROM [SP];
RETF
.ENDP;
-
16進制
+關注
關注
1文章
13瀏覽量
8767 -
BCD碼
+關注
關注
1文章
52瀏覽量
18291 -
8421碼
+關注
關注
1文章
8瀏覽量
4040
發(fā)布評論請先 登錄
相關推薦
評論