📄 hextobcd.asm
字号:
_HEX_BCD:CLR A ;目标数据清零初始化
MOV bcdData, A
MOV bcdData+1, A
MOV bcdData+2, A
MOV R2, #15 ; 共进行15次循环移位运算
H_B0: MOV A, R7 ; 低8位
RLC A ; 大循环左移
MOV R7, A ; 回存
MOV A, R6 ; 高8位
RLC A ; 大循环左移
MOV R6, A ; 回存。至此已获得当前数据的最高位
MOV A, bcdData+2 ; 目标数最低8位
RLC A ; 移入原数据的最高位
ACALL _BCD_ADJ ; 压缩BCD码的十进制调整
MOV bcdData+2, A ; 存回
MOV A, bcdData+1 ; 目标数中间8位
RLC A ; 移入进位位
ACALL _BCD_ADJ ; 压缩BCD码的十进制调整
MOV bcdData+1, A ; 存回
MOV A, bcdData ; 目标数最高8位
RLC A ; 移入进位位
ACALL _BCD_ADJ ; 压缩BCD码的十进制调整
MOV bcdData, A ; 存回
DJNZ R2, H_B0 ; 继续下一轮循环
; 目标数据再左移一位,将原数据的最后一位放入,这样总共进行了16次循环移位
MOV A, R6
RLC A
MOV A, bcdData+2
RLC A
MOV bcdData+2, A
MOV A, bcdData+1
RLC A
MOV bcdData+1, A
MOV A, bcdData
RLC A
MOV bcdData, A
RET
;*************************************************************************
; 压缩BCD码的十进制调整,基本思路:逢十进一,在这里因为还保留着最后一次左
; 移, 所以进位判别的0AH(0A0H)变成相对右移了一位的05H(050H), 而强迫进行进位
; 的方法是加上一个数字3(左移一位后就是6)。程序保护PSW
; 输入返回均使用Acc累加器
;*************************************************************************
RSEG ?PR?_BCD_ADJ?HEX_BCD
_BCD_ADJ:
PUSH PSW
PUSH ACC
CJNE A, #50H, $+3 ; 高4位。做一个比较产生状态标志
JC B1 ; 如果小于#50H, 不用进位处理
POP ACC ; 取原数据作修改
ADD A, #30H ; 加上#30h,留待下一轮左移时产生进位
PUSH ACC ; 存回原数据
B1: ANL A, #0FH ; 仅考虑低4位
CJNE A, #5, $+3 ; 做一个比较产生状态标志
JC B2 ; 如果小于#5H, 不用进位处理
POP ACC ; 取原数据作修改
ADD A, #3 ; 加上#3h,留待下一轮左移时产生进位
PUSH ACC ; 存回原数据
B2: POP ACC ; 恢复现场
POP PSW
RET
end
/////////////////////////////////////////////////
[nobody]?的快速算法,速度更快。
//////////////////////////////////////////////////////
?PR?_HEX_BCD?HEX_BCD SEGMENT CODE
PUBLIC _HEX_BCD
RSEG ?PR?_HEX_BCD?HEX_BCD
_HEX_BCD:
CLR A ;BCD码初始化
MOV R3,A
MOV R4,A
MOV R5,A
MOV R2,#10H ;转换双字节十六进制整数
HB3:
MOV A,R7 ;从高端移出待转换数的一位到CY中
RLC A
MOV R7,A
MOV A,R6
RLC A
MOV R6,A
MOV A,R3 ;BCD码带进位自身相加,相当于乘2
ADDC A,R3
DA A ;十进制调整
MOV R3,A
MOV A,R4
ADDC A,R4
DA A
MOV R4,A
MOV A,R5
ADDC A,R5
MOV R5,A ;双字节十六进制数的万位数不超过6,不用调整
DJNZ R2,HB3 ;处理完16bit
mov a,r3
mov r7,a
mov a,r4
mov r6,a
mov r4,#0
RET
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -