2

我正在做一个 iPhone/iPad 项目,我想在一些(不是全部)算术运算期间更新状态寄存器。默认情况下,Xcode 使用“Compile for Thumb”,我不想更改它。

以下 GCC 内联汇编代码在 ARM 下运行良好,但在 Thumb 下导致编译错误:'instruction not supported in Thumb16 mode - 添加 r6、r4、r5'。问题在于状态寄存器更新。(我也知道movcs并且strcs需要更改)。

Thumb 是否有在 CPSR 中设置溢出 (V) 或进位 (C) 的 ADD 指令?如果没有,是否有特定于 Thumb 的汇编级解决方法来测试溢出和进位?

uint32_t result, a, b;
int no_carry = 1;
...

__asm__
(
  "ldr  r4, %[xa]   ;"  // R4 = a
  "ldr  r5, %[xb]   ;"  // R5 = b
  "adds r6, r4, r5  ;"  // R6 = R4 + R5, set status
  "movcs    r4, #0      ;"  // set overflow (if carry set)
  "strcs    r4, %[xc]   ;"  // store it (if carry set)
  "str  r6, %[xr]   ;"  // result = R6
  : [xr] "=m" (result), [xc] "=m" (no_carry)
  : [xa] "m" (a), [xb] "m" (b)
  : "r4", "r5", "r6"
);

...

编辑:还需要移动寄存器以利用ARM ABI at Application Binary Interface (ABI) for the ARM Architecture

4

3 回答 3

4

我对 XCode 和 Apple 的工具链不是很熟悉,但我怀疑它可能期望以旧的、前 UAL 形式的程序集。ADD 的 Thumb-16 编码总是设置标志(用于寄存器 R0-R7),但是,在 UAL 之前的汇编中,S 没有添加到助记符中。(大多数算术运算总是更新 Thumb-16 中的标志,因此暗示了 S。)因此,您应该尝试.syntax_unified在汇编块的开头添加,或者使用简单的 ADD 助记符。

但是,您的代码中还有另一个问题。Thumb-16 不支持条件指令,只支持条件分支。所以你将不得不使用分支重做你的代码,或者使用 ADC/SBC。

请注意,以上所有内容仅适用于原始 Thumb ISA(又名 Thumb-16)。Thumb-2(又名 Thumb-32)可以(几乎)做 ARM 可以做的任何事情,包括使用高位寄存器和条件指令,但它在 ARMv6 目标中不可用(这可能是 XCode 中的默认设置)。

于 2011-06-20T10:21:22.280 回答
4

伊戈尔建议使用“.syntax_unified”。但是,至少对于 binutils 2.22,命令是“.sytax 统一的”。以下示例在这里编译得很好:

.align  4
.code   16
.syntax unified

adds r0,r0,r2
adc  r1,r1,r3
于 2012-05-31T21:27:04.470 回答
0

根据Thumb-16 快速参考指南,该ADDS说明应该可用。这似乎是汇编程序中的一个错误(@dwelch 已确认)。

我发现我可以通过发出使用汇编指令预先编码的指令来解决它。例如:

__asm__
(
  "ldr  r0, %[xa]   ;"  // R0 = a
  "ldr  r1, %[xb]   ;"  // R1 = b
  "adds r1, r1, r0  ;"  // R1 = a + b
  ...
);

将使用以下方法实现:

__asm__
(
  "ldr  r0, %[xa]   ;"  // R0 = a
  "ldr  r1, %[xb]   ;"  // R1 = b
  ".inst.w 0x1809   ;"  // Issue 'adds r1, r1, r0'
  ...
);

如果我愿意adds r2, r2, r1,代码应该发出.inst.w 0x1852,依此类推。

编辑:由于arm thumb2 ldr.w 语法,最近更新了代码?在 Binutils 邮件列表中。

于 2011-06-23T04:24:26.353 回答