I find some code really works, but I don't know why this code works.
why combining RCL and ADC could convert the binary to decimal, is this algorithm a nice one?
how to explain this, are there any better code?
;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[]
holds the result (packed BCD) which is initially set to 0. At every shift-left of the 48-bit integer (RCL...RCL...RCL
) the result is multiplied by 2 and the isolated binary digit (shifted bit) is added (ADC AL, AL
). The principle is the same as with converting a decimal number into an integer (multiply by ten and add the isolated decimal digit).DAA
handles the overflows after an addition. The carry of the very firstADC
comes from the last RCL, but the followingADC
take the carry flags fromDAA
.Advantage:
Disadvantage:
BTW: Your "input" is handled as "big endian", while "buffer" results in "little endian". You will be in trouble at least when you want to play with 32-bit registers (e.g. EAX - yes, you can address them in 16-bit mode).