4

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

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)

但是每次我在不同的函数中使用宏时,我都必须转换Atype没有类型错误或type正确给出。

4

1 回答 1

2

使用 GCC,有一个捷径:

register long r0 asm ("r0");

然后r0“别名”该寄存器。

将它与语句表达式结合起来,你甚至可以得到r0一个“返回值”。

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

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

请参阅扩展程序集本地 reg vars

于 2012-05-31T10:30:40.800 回答