Assembly BCD加法汇编程序逻辑
下面我试图理解一个x86转储加法程序中的汇编程序片段,其中添加了两个数字6789和1234,问题是这个程序如何处理进位 当结果大于9时,我知道加6,但这个程序有太多步骤,对我来说毫无意义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
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