如何在x8086汇编中将二进制转换为十进制?
How to convert binary into decimal in assembly x8086?
我发现一些代码确实有效,但我不知道为什么这段代码有效。
为什么结合RCL和ADC可以将二进制转十进制,这个算法好吗?
这个怎么解释,有没有更好的代码?
;input=R5R6R7
;output=buffer0 - buffer7
DATA SEGMENT
R0 DW (?) ;0000H
R1 DW (?) ;0002H
R2 DW (?) ;0004H
R3 DW (?) ;0006H
R4 DW (?) ;0008H
R5 DW (?) ;000AH
R6 DW (?) ;000CH
R7 DW (?) ;000EH
buffer0 DB (?) ;001CH
buffer1 DB (?)
buffer2 DB (?)
buffer3 DB (?)
buffer4 DB (?)
buffer5 DB (?)
buffer6 DB (?)
buffer7 DB (?)
buffer8 DB (?)
buffer9 DB (?)
DATA ENDS
BCTD PROC NEAR
MOV CX, 8
LEA BX, [buffer0]
CLR_BUFFER:
MOV BYTE PTR [BX], 0
INC BX
LOOP CLR_BUFFER
MOV CX, 48
BCTD_LOOP:
CLC
RCL R7, 1
RCL R6, 1
RCL R5, 1
MOV AL, buffer0
ADC AL, AL
DAA
MOV buffer0, AL
MOV AL, buffer1
ADC AL, AL
DAA
MOV buffer1, AL
MOV AL, buffer2
ADC AL, AL
DAA
MOV buffer2, AL
MOV AL, buffer3
ADC AL, AL
DAA
MOV buffer3, AL
MOV AL, buffer4
ADC AL, AL
DAA
MOV buffer4, AL
MOV AL, buffer5
ADC AL, AL
DAA
MOV buffer5, AL
MOV AL, buffer6
ADC AL, AL
DAA
MOV buffer6, AL
MOV AL, buffer7
ADC AL, AL
DAA
MOV buffer7, AL
LOOP BCTD_LOOP
RET
BCTD ENDP
buffer[]
保存初始设置为 0 的结果(压缩 BCD)。在 48 位整数 (RCL...RCL...RCL
) 的每个左移处,结果乘以 2,然后添加孤立的二进制数字(移位位)(ADC AL, AL
)。原理与将十进制数转换为整数(乘以十并加上孤立的十进制数字)相同。 DAA
处理添加后的溢出。第一个 ADC
的进位来自最后一个 RCL,但接下来的 ADC
从 DAA
.
获取进位标志
优势:
- 没有划分。
- 代码可以很容易地调整为更大的整数。
缺点:
- 结果是 BCD 压缩的。您需要一些努力才能将其转换为
十进制 ASCII 字符串。
- 前导零。
- 整个循环必须 运行
每种情况下的位数。这对于较小的整数来说很昂贵。
顺便说一句:您的 "input" 被处理为 "big endian",而 "buffer" 结果为 "little endian"。至少当你想玩 32 位寄存器时你会遇到麻烦(例如 EAX - 是的,你可以在 16 位模式下寻址它们)。
我发现一些代码确实有效,但我不知道为什么这段代码有效。
为什么结合RCL和ADC可以将二进制转十进制,这个算法好吗?
这个怎么解释,有没有更好的代码?
;input=R5R6R7
;output=buffer0 - buffer7
DATA SEGMENT
R0 DW (?) ;0000H
R1 DW (?) ;0002H
R2 DW (?) ;0004H
R3 DW (?) ;0006H
R4 DW (?) ;0008H
R5 DW (?) ;000AH
R6 DW (?) ;000CH
R7 DW (?) ;000EH
buffer0 DB (?) ;001CH
buffer1 DB (?)
buffer2 DB (?)
buffer3 DB (?)
buffer4 DB (?)
buffer5 DB (?)
buffer6 DB (?)
buffer7 DB (?)
buffer8 DB (?)
buffer9 DB (?)
DATA ENDS
BCTD PROC NEAR
MOV CX, 8
LEA BX, [buffer0]
CLR_BUFFER:
MOV BYTE PTR [BX], 0
INC BX
LOOP CLR_BUFFER
MOV CX, 48
BCTD_LOOP:
CLC
RCL R7, 1
RCL R6, 1
RCL R5, 1
MOV AL, buffer0
ADC AL, AL
DAA
MOV buffer0, AL
MOV AL, buffer1
ADC AL, AL
DAA
MOV buffer1, AL
MOV AL, buffer2
ADC AL, AL
DAA
MOV buffer2, AL
MOV AL, buffer3
ADC AL, AL
DAA
MOV buffer3, AL
MOV AL, buffer4
ADC AL, AL
DAA
MOV buffer4, AL
MOV AL, buffer5
ADC AL, AL
DAA
MOV buffer5, AL
MOV AL, buffer6
ADC AL, AL
DAA
MOV buffer6, AL
MOV AL, buffer7
ADC AL, AL
DAA
MOV buffer7, AL
LOOP BCTD_LOOP
RET
BCTD ENDP
buffer[]
保存初始设置为 0 的结果(压缩 BCD)。在 48 位整数 (RCL...RCL...RCL
) 的每个左移处,结果乘以 2,然后添加孤立的二进制数字(移位位)(ADC AL, AL
)。原理与将十进制数转换为整数(乘以十并加上孤立的十进制数字)相同。 DAA
处理添加后的溢出。第一个 ADC
的进位来自最后一个 RCL,但接下来的 ADC
从 DAA
.
优势:
- 没有划分。
- 代码可以很容易地调整为更大的整数。
缺点:
- 结果是 BCD 压缩的。您需要一些努力才能将其转换为 十进制 ASCII 字符串。
- 前导零。
- 整个循环必须 运行 每种情况下的位数。这对于较小的整数来说很昂贵。
顺便说一句:您的 "input" 被处理为 "big endian",而 "buffer" 结果为 "little endian"。至少当你想玩 32 位寄存器时你会遇到麻烦(例如 EAX - 是的,你可以在 16 位模式下寻址它们)。