![](/img/trans.png)
[英]how to solve error in inline assembly in C: 'can't find a register in class 'GENERAL_REGS' while reloading 'asm''
[英]How to ask for a general purpose register in an asm inline statement?
有沒有一種方法可以要求gcc分配一個僅用於asm內聯內部使用的寄存器? 這是一個示例(在偽asm中),其中r5直接在asm中使用,但是它可以是任何通用寄存器,僅用於內部使用,因此既不是輸入也不是輸出:
asm("load_immediate_value %%r5,0;"
/* ... */
"add_immediate_value %%r5,%%r5,42"
/* ... */
:
:
: "r5");
在此示例中,我選擇寄存器r5,並通過Clobber列表告知gcc我正在使用它。 但是,如果r5是ABI寄存器怎么辦? 我需要一種方法來簡單地請求注冊,而無需自己命名。
通常這樣做的方式是:
static __inline__ void set_archctrl0(unsigned long val) {
register unsigned long archctrl0 __asm__("archctrl0") = val;
__asm__ __volatile__("" : "+r"(archctrl0) : : "cc", "memory");
}
空的 asm
語句僅用於迫使編譯器不優化整個過程。
或者,舉一個更實際的例子,讀取堆棧指針寄存器可以像這樣完成:
static __inline__ void * getSP(void) {
register void * sp asm("sp");
asm ("" : "=r"(sp));
return sp;
}
將變量綁定到特定寄存器的方法在GCC手冊的“ 顯式寄存器變量”部分中進行了介紹。
當然,如果編寫特定於拱的寄存器需要一條自定義指令(即無法使用CPU通常用於初始化寄存器值的任何類型的“移動”或“裝載”來完成),則您需要以下內容:
static __inline__ void set_archctrl0(unsigned long val) {
__asm__ __volatile__("setarchctrl0 %0" : : "r"(val) : "cc", "memory");
}
顯然,所有這些僅適用於未被 “正常”代碼使用的寄存器(即,在平台ABI外部/平台ABI明確保留為全局變量/編譯代碼不會觸及的regs)。
您不能通過這種方式指示編譯器“將其手從通用寄存器中移開”。 據我所知,這在gcc中是不可能的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.