0

请注意:我只是想学习。请不要因为我玩弄组装而对我大喊大叫。

我有以下方法:

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

我根据在这里找到的详细信息创建了一个 .s 文件。

我的 .s 文件包含以下内容:

.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

因此,如果我调用以下命令:

addFunction(10,20)

我得到了我所期望的。但是如果我尝试

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

两个值的截图

我的 addOne 最终与我的 add 2 的值不同。关于我在这里做错了什么的任何想法?

4

2 回答 2

2

当您将int16_t参数传递0xffffaddFunction编译器时,将其符号扩展以适合 32 位寄存器(因为它是有符号整数),使其成为0xffffffff.您将其中两个加在一起以获取0xfffffffe并返回它。当您这样做时,0xffff + 0xffff这两个常量已经是 32 位,因此无需对扩展进行签名,结果为0x0001fffe.

您需要了解的是,当您使用有符号整数并传递 16 位值0xffff时,您实际上是在-1传递-1 + -1 = -2. 这也不足为奇0xffff + 0xffff = 0xfffffffe

如果您更改(未显示)C 声明addFunction以采用两个无符号整数,那么您将获得您想要的结果(编译器不会进行符号扩展)。

于 2012-09-20T12:51:11.467 回答
0

您的汇编代码假定第三个传递参数(在 R2 中),但是当您调用该函数时,您只传递了 2 个参数。我认为 R2 的内容可以是您 addFunction 中的任何内容。

于 2012-09-19T19:52:17.013 回答