6502 汇编二进制文件到 bcd - 在 x86 上可能吗?
6502 assembly binary to bcd - is that possible on x86?
关于这段代码我有几个问题:
; Convert an 16 bit binary value to BCD
;
; This function converts a 16 bit binary value into a 24 bit BCD. It
; works by transferring one bit a time from the source and adding it
; into a BCD value that is being doubled on each iteration. As all the
; arithmetic is being done in BCD the result is a binary to decimal
; conversion. All conversions take 915 clock cycles.
;
; See BINBCD8 for more details of its operation.
;
; Andrew Jacobs, 28-Feb-2004
.ORG 00
BINBCD16: SED ; Switch to decimal mode
LDA #0 ; Ensure the result is clear
STA BCD+0
STA BCD+1
STA BCD+2
LDX #16 ; The number of source bits
CNVBIT: ASL BIN+0 ; Shift out one bit
ROL BIN+1
LDA BCD+0 ; And add into result
ADC BCD+0
STA BCD+0
LDA BCD+1 ; propagating any carry
ADC BCD+1
STA BCD+1
LDA BCD+2 ; ... thru whole result
ADC BCD+2
STA BCD+2
DEX ; And repeat for next bit
BNE CNVBIT
CLD ; Back to binary
BRK ; All Done.
; A test value to be converted
.ORG 00
BIN .DW 12345
BCD .DS 3
来自 this 站点。
我不明白这行到底是做什么的:
ROL BIN+1
是否对BIN的第二个字节进行右移?如果是这样,这个字节到底是什么?
也可以为 x86 编写类似的东西吗?是否可以使用 BCD 以某种优雅的方式使用 x86 打印十进制数字?或者最好坚持除以 10? AAA、AAM指令我知道一些,但不知道有没有用。
ROL
= 向左旋转。是的,那是第二个字节。 ASL
+ROL
一起将BIN
和BIN+1
中的16位数字左移一位。 ROL
用于将低字节的 MSB 传播到高字节的 LSB,同时将高字节的 MSB 移动到 ADC
指令使用的进位标志。
请注意此代码使用压缩 BCD,因此在 x86 上您需要使用 DAA 而不是 AAA 指令。此外,BCD 内容已被弃用,并且在 64 位模式下不可用。然而,这里是等效的 x86 代码,添加了文本转换和打印。 GNU 汇编器 at&t,32 位 linux:
.globl main
main:
sub , %esp
mov 345, %edx
mov , %ecx
repeat:
shl %dx
mov bcd, %al
adc %al, %al
daa
mov %al, bcd
mov bcd+1, %al
adc %al, %al
daa
mov %al, bcd+1
mov bcd+2, %al
adc %al, %al
daa
mov %al, bcd+2
dec %ecx
jnz repeat
# print
lea bcd+2, %esi
lea txt, %edi
call unpack
call unpack
call unpack
push $txt
call puts
call exit
unpack:
mov (%esi), %al
dec %esi
mov %al, %ah
shr , %al
and , %ah
add [=10=]x3030, %ax
stosw
ret
.lcomm bcd, 3
.lcomm txt, 7
以上不是推荐的泛型 int-to-string 方法,它只是问题中 6502 代码的翻译。
关于这段代码我有几个问题:
; Convert an 16 bit binary value to BCD
;
; This function converts a 16 bit binary value into a 24 bit BCD. It
; works by transferring one bit a time from the source and adding it
; into a BCD value that is being doubled on each iteration. As all the
; arithmetic is being done in BCD the result is a binary to decimal
; conversion. All conversions take 915 clock cycles.
;
; See BINBCD8 for more details of its operation.
;
; Andrew Jacobs, 28-Feb-2004
.ORG 00
BINBCD16: SED ; Switch to decimal mode
LDA #0 ; Ensure the result is clear
STA BCD+0
STA BCD+1
STA BCD+2
LDX #16 ; The number of source bits
CNVBIT: ASL BIN+0 ; Shift out one bit
ROL BIN+1
LDA BCD+0 ; And add into result
ADC BCD+0
STA BCD+0
LDA BCD+1 ; propagating any carry
ADC BCD+1
STA BCD+1
LDA BCD+2 ; ... thru whole result
ADC BCD+2
STA BCD+2
DEX ; And repeat for next bit
BNE CNVBIT
CLD ; Back to binary
BRK ; All Done.
; A test value to be converted
.ORG 00
BIN .DW 12345
BCD .DS 3
来自 this 站点。
我不明白这行到底是做什么的:
ROL BIN+1
是否对BIN的第二个字节进行右移?如果是这样,这个字节到底是什么?
也可以为 x86 编写类似的东西吗?是否可以使用 BCD 以某种优雅的方式使用 x86 打印十进制数字?或者最好坚持除以 10? AAA、AAM指令我知道一些,但不知道有没有用。
ROL
= 向左旋转。是的,那是第二个字节。 ASL
+ROL
一起将BIN
和BIN+1
中的16位数字左移一位。 ROL
用于将低字节的 MSB 传播到高字节的 LSB,同时将高字节的 MSB 移动到 ADC
指令使用的进位标志。
请注意此代码使用压缩 BCD,因此在 x86 上您需要使用 DAA 而不是 AAA 指令。此外,BCD 内容已被弃用,并且在 64 位模式下不可用。然而,这里是等效的 x86 代码,添加了文本转换和打印。 GNU 汇编器 at&t,32 位 linux:
.globl main
main:
sub , %esp
mov 345, %edx
mov , %ecx
repeat:
shl %dx
mov bcd, %al
adc %al, %al
daa
mov %al, bcd
mov bcd+1, %al
adc %al, %al
daa
mov %al, bcd+1
mov bcd+2, %al
adc %al, %al
daa
mov %al, bcd+2
dec %ecx
jnz repeat
# print
lea bcd+2, %esi
lea txt, %edi
call unpack
call unpack
call unpack
push $txt
call puts
call exit
unpack:
mov (%esi), %al
dec %esi
mov %al, %ah
shr , %al
and , %ah
add [=10=]x3030, %ax
stosw
ret
.lcomm bcd, 3
.lcomm txt, 7
以上不是推荐的泛型 int-to-string 方法,它只是问题中 6502 代码的翻译。