1

I have the following 2 ARM instructions in a basic block which is part of a function that I'm trying to convert to C.

ADDS r4, r2, r7
ADC  r5, r3, r7, ASR#31

From my understanding, the first instruction does a r4 = r2+r7 and sets the flags. The next instruction does r5 = r3 + (r7>>31) + <carryflag>. How would the instructions look in C?

2

There is no single C instruction that matches the assembly code directly. What's happening is the 32 bit value in r7 gets added to the 64 bit value in r2/r3, with the result written to r4/r5.

You can verify this in a few different cases:

  • No overflow in the first instruction, positive number (bit 31 is zero) in r7. This means the ADC has nothing to add, and just copies r3 to r5.
  • First instruction produces overflow, but r7 is positive anyway. The ADC adds one (from the carry flag) to account for the overflow.
  • r7 is negative (bit 31 is 1). The ASR instruction produces a -1 (all bits set), since it does an arithmetic shift, not a logical shift. This effectively subtracts 1 from r3 in the second instruction.

So the original C code probably looked like this:

__int64__ r23;
__int32__ r7;
__int64__ r45;
r45=r23+r7;

As i said, the asm code doesn't really match the C code, since C doesn't have any syntax for type extension. (You could use casts in your C, but that wouldn't really make anything clearer).

This is one of the reasons why there is more to reverse engineering that just creating C from assembly; you have to have an understanding on assembly, registers, processor quirks, and compiler shortcuts, to understand what's going on in these cases.

  • Thanks! Is this a common pattern that can be noticed when doing 64 bit addition on 32 bit systems? – user1743 Jun 8 '15 at 20:19
  • 1
    yes, that's what the carry flag and adc is for - add the low part first, then add the high part and a possible carry bit. This was much more common on 16 bit processors, when dealing with 32 bit values. What's special here is how extension from 32 to 64 bits and adding with carry can be done in one single instruction on ARM. – Guntram Blohm supports Monica Jun 8 '15 at 23:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy