16位二进制转换成BCD码:
程序功能:将R17、R16中的16位二进制转换成BCD码,个、十、百、千和万位分别存放于R16、R17、R18、R19和R20中。
程序思想:R17、R16中的数,若够减10000有X次,则万位为X。若差值够减1000有Y次,则千位为Y。若差值够减100有Z次,则百位为Z。若差值够减10有U次,则十位为U。若差值为个位。
程序清单如下:
;---------------------------Start Binary 16 To Dicamal 5--------------------
;-----------Binary 16 To Dicamal 5;16位二进制转换成5位10进制。
B16TD5: ser R20 ;R20先送1
B16TD5_1: inc R20; ;R20增1
subi R16,Low(10000) ;R17:R16-10000
sbci R17,High(10000)
brcc B16TD5_1 ;够减,则返回B16TD5_1
subi R16,Low(-10000) ;不够减,+10000恢复余数
sbci R17,High(-10000) ;
ser R19 ;R19先送1
;------------------------------------------------------
B16TD5_2: inc R19; ;R19增1
subi R16,Low(1000) ;R17:R16-1000
sbci R17,High(1000)
brcc B16TD5_2 ;够减,则返回B16TD5_2
subi R16,Low(-1000) ;不够减,+1000恢复余数
sbci R17,High(-1000) ;
ser R18 ;R18先送1
;------------------------------------------------------
B16TD5_3: inc R18; ;R18增1
subi R16,Low(100) ;R17:R16-100
sbci R17,High(100)
brcc B16TD5_2 ;够减,则返回B16TD5_3
subi R16,Low(-100) ;不够减,+100恢复余数
sbci R17,High(-100) ;
ser R17 ;R17先送1
;------------------------------------------------------
B16TD5_4: inc R17; ;R17增1
subi R16,10 ;R17:R16-10
brcc B16TD5_4 ;够减,则返回B16TD5_4
subi R16,-10 ;不够减,+10恢复余数
ret
;-------------------------End Binary 16 To Dicamal 5-------------------
;====================================================================================
5位BCD码到16位二进制的转换:
程序功能:将个、十、百、千和万位分别存放于R16、R17、R18、R19和R20中的5位BCD码转换为16位二进制数,存放于R17、R16中。
程序思想:R16+10*R17+100*R18+1000*R19+10000*R20 = R17 R16 。
程序清单如下:
;----------------------Start Dicamal 5 To Binary 16-----------------------
D5TB16: tst R17 ;测试R17
rjmp D5TB16_2
;----------------------------------------
D5TB16_1: subi R16,-10 ;R16加10
dec R17 ;R17减1
;----------------------------------------
D5TB16_2: brne D5TB16_1 ;非0,转D5TB16_1
tst R18 ;测试R18
rjmp D5TB16_4
;----------------------------------------
D5TB16_3: subi R16,Low(-100) ;R17:R16加100
sbci R17,High(-100)
dec R18 ;R18减1
;----------------------------------------
D5TB16_4: brne D5TB16_3 ;非0,转D5TB16_3
tst R19 ;测试R19
rjmp D5TB16_6
;----------------------------------------
D5TB16_5: subi R16,Low(-1000) ;R17:R16加1000
sbci R17,High(-1000)
dec R19 ;R19减1
;----------------------------------------
D5TB16_6: brne D5TB16_5 ;非0,转D5TB16_5
tst R20 ;测试R20
rjmp D5TB16_8
;----------------------------------------
D5TB16_7: subi R16,Low(-10000) ;R17:R16加10000
sbci R17,High(-10000)
dec R20 ;R20减1
;---------------------------------------
D5TB16_8: brne D5TB16_7 ;非0,转D5TB16_7
ret
;-----------------------End Dicamal 5 To Binary 16-----------------------
;===========================================================================================
5位压缩BCD码到16位二进制的转换:
程序功能:5位压缩BCD码存放于[(高半字节)R18、R17、R16(低半字节)](R18高4位为0),二进制数存放于R17、R16中。
程序思想:先将压缩BCD码转换为BCD码放到R16(个)、R17(十)、R18(百)、R19(千)、R20(万)5个字节中,在调用D5TB16子程序即可.
程序清单如下:
;---------------------Start------------------------------------------
YD5TB16: mov R20,R18 ;取出万位
;-------------------------------------
mov R19,R17 ;令R19=R17
mov R18,R17 ;令R18=R17
mov R17,R16 ;令R17=R16
;-------------------------------------
andi R16,0x0f ;取出个位
andi R17,0xf0 ;
;-------------------------------------
swap R17 ;取出十位
;-------------------------------------
andi R18,0x0f ;取出百位
andi R19,0xf0 ;
;-------------------------------------
swap R19 ;取出千位
;-------------------------------------
rcall D5TB16 ;调用D5TB16,5位BCD到16位二进制的转换.
ret
;-----------------------End-----------------------------------------
;===================================================================================================
以下列出了16位加法、16位带立即数加法、16位减法、16位带立即数减法、16位比较、16位带立即数比较和16位取补程序。
一般负数以补码表示,最高位为符号位。
add16: add R16,R18 ;R17:R16+R19:R18--->R17:R16
adc R17,R19
;-------------------------------------------------
addi16: subi R16,Low(-addi2) ;R17:R16+addi2--->R17:R16
sbci R17,High(-addi2);addi2为16位立即数
;-------------------------------------------------
sub16: sub R16,R18 ;R17:R16-R19:R18--->R17:R16
sbc R17,R19
;-------------------------------------------------
subi16: subi R16,Low(-subi2) ;R17:R16-subi2--->R17:R16
sbci R17,High(-subi2);subi2为16位立即数
;-------------------------------------------------
cp16: cp R16,R18 ;R17:R16与R19:R18相比较
cpc R17,R19
;-------------------------------------------------
cpi16: cpi R16,Low(cp2) ;R17:R16与16为立即数cp2相比较
ldi R18,High(cp2)
cpc R17,R18
;-------------------------------------------------
beg16: com R16 ; R17:R16取补并回存
com R17 ;
subi R16,Low(-1)
sbci R17,High(-1)
;-------------------------------------------------
;==========================================================
32位运算与16位运算相似,32位加法程序和32位减法程序事例如下:
ADD32: add R16,R20 ;R19:R18:R17:R16+R23:R22:R21:R20--->R19:R18:R17:R16
adc R17,R21 ;
adc R18,R22 ;
adc R19,R23 ;
;----------------------------------------------------------
SUB32: sub R16,R20 ;R19:R18:R17:R16-R23:R22:R21:R20--->R19:R18:R17:R16
sbc R17,R21 ;
sbc R18,R22 ;
sbc R19,R23 ;
;----------------------------------------------------------------
;=========================8位/8位无符号除法================================
程序功能:R16(被除数)/R17(除数)--->R16(结果)...R15(余数)
该程序是将两个寄存器R16和R17相除,结果送至寄存器R16,余数送R15。
程序清单如下:
div8u: ;8位/8位无符号除法
sub R15,R15 ;清余数和进位
ldi R18,9 ;初始化循环计数器
d8u_1: rol R16 ;左移结果被除数
dec R18 ;减计数器
brne d8u_2 ;不为0,跳至d8u_2
ret
d8u_2: rol R15 ;左移余数被除数移到除数
sub R15,R17 ;余数除数
brcc d8u_3 ;够减,跳至d8u_3
add R15,R17 ;不够减,再加除数
clc ;清进位位
rjmp d8u_1 ;
d8u_3: sec ;置进位位
rjmp d8u_1 ;
;--------------------------------------------------------------------------
;=========================8位/8位带符号除法================================
程序功能:R16(被除数)/R17(除数)--->R16(结果)...R15(余数)
该程序是将两个寄存器R16和R17相除,结果送至寄存器R16,余数送R15。R16最高位为0,代表结果为正数;为1,则为负数。
程序清单如下:
div8s: ;8位/8位带符号除法
mov R14,R16 ;确定结果符号
eor R14,R17 ;
sbrc R17,7 ;判断除数的正负
neg R17 ;为负数,除数取补
sbrc R16,7 ;判断被除数的正负
neg R16 ;为负数,被除数取补
sub R15,R15 ;清余数和进位
ldi R18,9 ;初始化循环计数器
d8s_1: rol R16 ;左移结果被除数
dec R18 ;减计数器
brne d8s_2 ;不为0,跳至d8s_2
sbrc R14,7 ;判断结果的正负
neg R16 ; 为负,结果取补
ret
d8s_2: rol R15 ;左移余数被除数移到除数
sub R15,R17 ;余数除数
brcc d8s_3 ;够减,跳至d8u_3
add R15,R17 ;不够减,再加除数
clc ;清进位位
rjmp d8s_1 ;
d8s_3: sec ;置进位位
rjmp d8s_1
;--------------------------------------------------------------------------
;======================16位/8位无符号除法============================
程序功能:R16:R15(被除数)/R17(除数)--->R16(结果)...R15(余数)
该程序是将寄存器R16和R15的值与寄存器R17的值相除,结果送至寄存器R16,余数送R15,结果为8位。
程序清单如下:
d16v8u: ;16位/8位无符号除法
cp R16,R17 ;被除数高字节>除数
brcc ddd ;结果溢出
ldi R18,8 ;初始化循环计数器
rol R15 ;左移余数被除数低字节
aaa: bst R16,7 ;
rol R16 ;左移被除数高字节
sub R16,R17;R16-R17-->R16
brts bbb
brcc bbb
add R16,R17;结果为负,则R16加R17
clc
rjmp ccc
bbb: sec ;够减置进位位
ccc: rol R15 ;左移余数
dec R18 ;减计数器
brne