Reputation: 95
I am trying to understand below snippet of assembly program from an x86 dump for addition program, where two numbers 6789 and 1234 is added, the problem is how this program deals with carries.
I know adding 6, when result is greater than 9, but this program has so many steps that make little sense to me.
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
Upvotes: 1
Views: 1507
Reputation: 95
below I am presenting my own explaination of question , please correct me if am wrong
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
Upvotes: 0
Reputation: 64904
add ecx, F6F6F6F6
This makes the carries propagate, out of the digits that are >9 by adding 6, and passing the holes by adding F. 10 + 6 will result in 16 or more, so there's a carry out of this nibble into the next nibble. F plus that carry makes the carry propagate into the next nibble, and leaves a 0 where the carry went through.
and eax, 60606060
This produces a mask containing a 6 for every hole that a carry did not pass through.
sub ecx, eax
Fixes the digits that didn't have a carry-out in the first step. They had a 6 added to them before but didn't wrap so they're somewhere in [6..F], now that 6 is subtracted from them again.
Upvotes: 3