如何在ARM内联汇编程序中使用特定寄存器

时间:2012-05-31 10:27:25

标签: c gcc arm inline-assembly

我试图让内联汇编程序将一些值复制到特定的寄存器中,但它只会抱怨。这是将触发错误的代码的简短版本:

asm("" :: "r0" (value));
asm("" :: "a1" (value));

这两行都会触发:

Error: matching constraint references invalid operand number

那么如何指定直接采用的寄存器? 我知道我可以为这些值引入名称然后自己复制它们但是我想避免这种情况,因为这段代码会更短,更易读。

为什么我要问 目前我正在研究一些系统调用。我想使用这样的系统调用宏:

#define SYSCALL0(NUMBER) asm("swi #" STRINGIFY(NUMBER));
#define SYSCALL1(NUMBER, A) asm("swi #" STRINGIFY(NUMBER) :: "r0"(A));
#define SYSCALL2(NUMBER, A, B) asm("swi #" STRINGIFY(NUMBER) :: "r0"(A), "r1"(B));
...

正如你所看到的,它非常适合在线。 当然,我可以这样做:

#define SYSCALL1(NUMBER, A) register type R0 asm("r0") = A;
                            SYSCALL0(NUMBER)

但是我必须将A转换为type才能获得类型错误,或者每次都正确<{1}} 我在不同的函数中使用宏。

1 个答案:

答案 0 :(得分:1)

使用GCC,有一条捷径:

register long r0 asm ("r0");

然后r0“别名”注册。

将其与statement expression相结合,您甚至可以将r0作为“返回值”。

#define SYSCALL1(NUMBER,A) ({\
  register long r0 asm("r0") = (long) (A); \
  asm("swi #" STRINGIFY(NUMBER) : "=r"(r0) : "r"(r0) : "memory"); \
  r0; })

(我不知道clobber是否合法,但uClibc系统调用实现有这个。)

请参阅extended assemblylocal reg vars