1

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
Russia Must Remove Putin
  • 374,368
  • 89
  • 403
  • 331
naumaan
  • 55
  • 11

2 Answers2

3
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.

harold
  • 61,398
  • 6
  • 86
  • 164
  • What is holes ? Plz help , elaborate if possible – naumaan Feb 07 '17 at 10:06
  • 2
    @user143252 the places between the BCD digits that you're really working with, for example in 01020304 it's all the zeroes. I just called them holes because I thought that would make sense, it isn't really actual terminology as far as I know. – harold Feb 07 '17 at 10:24
  • 1
    @user143252 BCD numbers are packed per 4 bit groups, using only values 0 to 9 (not full 0-15 range of 4 bits). So properly BCD formatted number `1234` is `0x1234`. But in your code the input is taken from string probably? So `0x31323334` (`'1234'` ASCII string) is turned into `0x01020304` by the first `and`, which in BCD would work as value `1020304`, not `1234`. Remaining code is adjusted to work for every-odd BCD digit, jumping over the even ones. – Ped7g Feb 07 '17 at 13:47
  • It's unpacked bcd , 8 bits per digits , 4 msb bits holds sign or formating , 4 lsb bit holds data . – naumaan Feb 07 '17 at 13:50
  • Last 5 instruction is troubling me – naumaan Feb 07 '17 at 13:51
  • 2
    If you will take a look at the number after addition of `F6` pattern, and consider individual nibbles (4 bits, or packed BCD): `0xFE000203`, where the digit+6 was greater than 9, the next (hole) digit is 0, otherwise the next (hole) digit is 15. That is used to create value 0 or 6 in the even nibbles (`and F0 pattern`). Then the even digits are moved to position of odd digits (`shr 4`) and subtracted from original odd digits. So where the "a+b over `9`" (by `+F6`), there was `+6` left to adjust it to BCD value and the `F0` carried the +1 to next digit, any "a+b less/equal 9" is restored by -6. – Ped7g Feb 07 '17 at 14:08
0

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 
naumaan
  • 55
  • 11