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

My addOne does not end up being the same value as my add two. Any ideas on what I am doing wrong here?
When you pass the
int16_tparameter0xfffftoaddFunctionthe compiler sign-extends it to fit in the 32-bit register (as it’s a signed integer) making it0xffffffff.You add two of these together to get0xfffffffeand return it. When you do0xffff + 0xffffboth constants are already 32-bits and so there’s no need to sign extend, the result is0x0001fffe.What you need to understand is that when you’re using a signed integer and passing the 16-bit value
0xffffyou’re actually passing in-1, so it’s no surprise that-1 + -1 = -2. It’s also no suprise that0xffff + 0xffff = 0xfffffffe.If you change the (not shown) C declaration of
addFunctionto take two unsigned ints, then you’ll get the result you desire (the compiler won’t do the sign extension).