0

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?

4

2 に答える 2

2

int16_tパラメータ0xffffをコンパイラに渡すaddFunctionと、32ビットレジスタに収まるように符号拡張され(符号付き整数であるため)0xffffffff.、これらのうち2つを追加して取得0xfffffffeして返します。0xffff + 0xffff両方の定数がすでに 32 ビットであるため、符号拡張する必要がない場合、結果は0x0001fffe.

理解する必要があるのは、符号付き整数を使用して 16 ビット値0xffffを渡す場合、実際に を渡す-1ということ-1 + -1 = -2です。それも当然のこと0xffff + 0xffff = 0xfffffffeです。

(表示されていない) の C 宣言を 2 つのunsignedaddFunction intを取るように変更すると、希望する結果が得られます (コンパイラは符号拡張を行いません)。

于 2012-09-20T12:51:11.467 に答える
0

アセンブリ コードは、(R2 で) 3 番目に渡されたパラメーターを想定していますが、関数を呼び出すと、2 つのパラメーターしか渡されません。R2 の内容は、addFunction の中であれば何でもよいと思います。

于 2012-09-19T19:52:17.013 に答える