[英]How to use specific register in ARM inline assembler
我試圖讓內聯匯編器將某些值復制到特定的寄存器中,但它只會抱怨。 這是將觸發錯誤的代碼的簡短版本:
asm("" :: "r0" (value));
asm("" :: "a1" (value));
這兩行都將觸發:
Error: matching constraint references invalid operand number
那么,如何指定直接接受的寄存器? 我知道我可以為這些值引入名稱,然后由我自己復制它們,但是我想避免這種情況,因為這段代碼將更短,更易讀。
為什么我要問目前我正在從事一些系統調用。 我想使用像這樣的syscall宏:
#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
。
使用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; })
(我不知道該破壞者是否合法,但uClibc syscall實現中確實有此行為。)
請參閱擴展程序集和本地reg vars 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.