簡體   English   中英

如何在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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM