2012-05-31 116 views
1

我試圖讓內聯彙編程序將某些值複製到特定寄存器中,但它只是抱怨。這是代碼的短版,將觸發該錯誤:如何在ARM內聯彙編程序中使用特定寄存器

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正確每次我用宏在不同的功能。

回答

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; }) 

(我不知道,如果撞合法與否,uClibc的系統調用實現存在雖然)。

extended assemblylocal reg vars

+0

是的,我知道,但我不喜歡長的語法。我會更新我的問題以顯示我的動機。 – Nobody

+0

並非所有處理相同「C類型」(長)的寄存器? – Mat

+0

寄存器是這種類型的,但是進來的變量可以有任意類型(例如int,char *,void(fn *)(void),...),所以我必須每次都進行一次轉換。這不是不可能,但它確實很醜。 – Nobody

相關問題