Kyle
Kyle

Reputation: 17687

Attempt as assembly on iOS

Please note: I'm just trying to learn. Please do not yell at me for toying with assembly.

I have the following method:

uint32 test(int16 a, int16 b)
{
  return ( a + b ) & 0xffff;
}

I created a .s file based on details I found here.

My .s file contains the following:

.macro BEGIN_FUNCTION
.align 2        // Align the function code to a 4-byte (2^n) word boundary.
.arm            // Use ARM instructions instead of Thumb.
.globl _$0      // Make the function globally accessible.
.no_dead_strip _$0  // Stop the optimizer from ignoring this function!
.private_extern _$0
_$0:                // Declare the function.
.endmacro

.macro END_FUNCTION
bx  lr      // Jump back to the caller.
.endmacro


BEGIN_FUNCTION addFunction
  add       r0, r0, r1      // Return the sum of the first 2 function parameters
END_FUNCTION

BEGIN_FUNCTION addAndFunction
  add       r0, r0, r1      // Return the sum of the first 2 function parameters
  ands      r0, r0, r2      // Ands the result of r0 and the third parameter passed
END_FUNCTION

So if I call the following:

addFunction(10,20)

I get what I would expect. But then if I try

int addOne = addFunction(0xffff,0xffff); // Result = -2
int addTwo = 0xffff + 0xffff;            // Result = 131070

Screenshot of the two values

My addOne does not end up being the same value as my add two. Any ideas on what I am doing wrong here?

Upvotes: 0

Views: 161

Answers (2)

jleahy
jleahy

Reputation: 16895

When you pass the int16_t parameter 0xffff to addFunction the compiler sign-extends it to fit in the 32-bit register (as it's a signed integer) making it 0xffffffff. You add two of these together to get 0xfffffffe and return it. When you do 0xffff + 0xffff both constants are already 32-bits and so there's no need to sign extend, the result is 0x0001fffe.

What you need to understand is that when you're using a signed integer and passing the 16-bit value 0xffff you're actually passing in -1, so it's no surprise that -1 + -1 = -2. It's also no suprise that 0xffff + 0xffff = 0xfffffffe.

If you change the (not shown) C declaration of addFunction to take two unsigned ints, then you'll get the result you desire (the compiler won't do the sign extension).

Upvotes: 2

user1619508
user1619508

Reputation:

Your assembly code assumes a third passed parameter (in R2) but when you call the function you are only passing 2 parameters. I think the contents of R2 could be anything in your addFunction.

Upvotes: 0

Related Questions