Assembly BCD加法汇编程序逻辑

Assembly BCD加法汇编程序逻辑,assembly,x86,Assembly,X86,下面我试图理解一个x86转储加法程序中的汇编程序片段,其中添加了两个数字6789和1234,问题是这个程序如何处理进位 当结果大于9时,我知道加6,但这个程序有太多步骤,对我来说毫无意义 and ecx,0F0F0F0F // masking zoned bits -> 06 07 08 09 and eax,0F0F0F0F // masking zoned bits

下面我试图理解一个x86转储加法程序中的汇编程序片段,其中添加了两个数字6789和1234,问题是这个程序如何处理进位

当结果大于9时,我知道加6,但这个程序有太多步骤,对我来说毫无意义

and     ecx,0F0F0F0F           
              // masking zoned bits  -> 06 07 08 09
and     eax,0F0F0F0F              
            // masking zoned bits  -> 01 02 03 04
 add     ecx,eax         
            //  ecx value after addition 07 09 0B 0D (this is simple Binary add result,now need to convert it to BCD addition)

add     ecx,F6F6F6F6
            // after addition FE 00 02 03

mov     eax,ecx                  
             // eax = ecx = FE 00 02 03
and     eax,60606060
            // eax = 60 00 00 00
shr     eax,04 
            // eax = 06 00 00 00
and     ecx,0F0F0F0F
            // FE 00 02 03 & 0F 0F 0F 0F = 0E 00 02 03(ECX)
sub     ecx,eax 
            // 0E 00 02 03 - 06 00 00 00 = 08 00 02 03               // 8023 ans
这会使进位从大于9的数字中通过加6进行传播,并通过加F通过孔。10+6将导致16个或更多的进位,因此这一个半字节将进位到下一个半字节。F加上进位使进位传播到下一个半字节,并在进位经过的地方留下一个0

and eax, 60606060
这将生成一个掩码,其中每个孔的进位未通过的位置都包含一个6

sub ecx, eax

修复第一步中没有执行的数字。之前,它们添加了一个6,但没有包装,所以它们位于[6..F]中的某个位置,现在又从它们中减去了6。

下面我给出了我自己对问题的解释,如果我错了,请纠正我

add     ecx,eax 
            //  ecx value after addition 07 09 0B 0D (this is simple Binary addition result , now need to convert it to BCD addition)

add     ecx,F6F6F6F6
               // after addition FE 00 02 03        // adding 6 to each digit to correct it , its is greater or equal to 9 
                                // the position where zoned bits becomes zero that means its a correction , but digits where zoned bits are not zero that means no correction is needed there ,
                                //and there is excess 6 due to additon of f6 , now need to subtract the 6 from the number 

mov     eax,ecx            // eax = ecx = FE 00 02 03
and     eax,60606060..............// eax = 60 00 00 00 // the position where excess 6 is there , is identified by this step 

shr     eax,04 ...................// eax = 06 00 00 00  // we can correct it by shifing the 6 adjacent to digit where is excess 6 


and     ecx,0F0F0F0F..............// FE 00 02 03 & 0F 0F 0F 0F = 0E 00 02 03(ECX)        // proper format , masking irrevelant bits of ecx


sub     ecx,eax ..................// 0E 00 02 03 - 06 00 00 00 = 08 00 02 03               // 8023 ans       // subtracting excess 6 

什么是洞?请提供帮助,如果需要,请详细说明possible@user143252您实际使用的BCD数字之间的位置,例如在01020304中,都是零。我之所以称它们为洞,是因为我认为这是有意义的,据我所知,这并不是真正的术语。@user143252 BCD数字是按4位组打包的,只使用0到9的值(不是4位的0-15范围)。因此,正确BCD格式的数字
1234
0x1234
。但在您的代码中,输入可能来自字符串?因此,
0x31323334
'1234'
ASCII字符串)由第一个
转换为
0x01020304
,在BCD中作为值
1020304
,而不是
1234
。剩下的代码被调整为每一个奇数的BCD数字,跳过偶数的BCD,它是解压缩的BCD,每位数8个比特,4个MSB位持有符号或格式,4个LSB位保存数据。如果你在添加了<代码> F6< /代码>模式之后再看这个数字,并且考虑单个的字节(4位,或填充的BCD):<代码> 0xFE00203 < /代码>,如果数字+6大于9,则下一个(孔)数字为0,否则下一个(孔)数字为15。用于在偶数半字节(
和F0模式
)中创建值0或6的。然后将偶数移到奇数(
shr 4
)的位置,并从原始奇数中减去。因此,如果“a+b超过
9
”(通过
+F6
),则剩下
+6
将其调整为BCD值,并且
F0
将+1带到下一个数字,则任何“a+b小于/等于9”都由-6恢复。
add     ecx,eax 
            //  ecx value after addition 07 09 0B 0D (this is simple Binary addition result , now need to convert it to BCD addition)

add     ecx,F6F6F6F6
               // after addition FE 00 02 03        // adding 6 to each digit to correct it , its is greater or equal to 9 
                                // the position where zoned bits becomes zero that means its a correction , but digits where zoned bits are not zero that means no correction is needed there ,
                                //and there is excess 6 due to additon of f6 , now need to subtract the 6 from the number 

mov     eax,ecx            // eax = ecx = FE 00 02 03
and     eax,60606060..............// eax = 60 00 00 00 // the position where excess 6 is there , is identified by this step 

shr     eax,04 ...................// eax = 06 00 00 00  // we can correct it by shifing the 6 adjacent to digit where is excess 6 


and     ecx,0F0F0F0F..............// FE 00 02 03 & 0F 0F 0F 0F = 0E 00 02 03(ECX)        // proper format , masking irrevelant bits of ecx


sub     ecx,eax ..................// 0E 00 02 03 - 06 00 00 00 = 08 00 02 03               // 8023 ans       // subtracting excess 6