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

问题描述 投票:2回答:1

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

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以获得没有类型错误或每次我在不同的函数中使用宏时正确地给type

c gcc arm inline-assembly
1个回答
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

© www.soinside.com 2019 - 2024. All rights reserved.