簡體   English   中英

(GNU內聯匯編)如何使用既沒有分配也沒有復制到C變量的寄存器?

[英](GNU inline assembly) How to use a register which not assigned from nor copy to the C variables?

我正在使用基於GNU的工具鏈編寫內聯匯編語句,並且內聯匯編中包含三條指令來更新系統寄存器的單個位。 步驟將是:

  1. 將系統寄存器移動(讀取)到通用寄存器
  2. 將其與C代碼中的變量值“與”
  3. 移動(寫入)回到系統寄存器,只需讀取

在我使用的指令集中,內聯匯編語法如下:

unsigned int OV_TMP = 0xffefffff;
asm volatile ( "mfsr %0, $PSW\n\t"
               "and %0, %0, %1\n\t"
               "mtsr %0, $PSW"
               :  : "r"(OV_TMP) : );

%1是我要將OV_TMP的值轉發到的寄存器。

%0對我來說是問題,我的問題是: 一旦內部使用了一個寄存器,並且未從C代碼的C變量中分配或復制到該變量,如何編寫內聯匯編代碼?

從編譯器的角度來看,這里要考慮的事情是,即使您以后不再使用它,寄存器由內聯程序集分配給它。 也就是說,您生成的等效項是:

register unsigned int OV_TMP = 0xffefffff, scratch;

scratch = magic() & OV_TMP;
more_magic(scratch);
/* and then don't re-use scratch for anything from here on */

由於volatile ,魔術步驟和/或more_magic步驟無法移動或合並,因此編譯器不能簡單地刪除已寫入但未使用的寄存器。

在我看來, mfsrmtsr就像是powerpc指令,我可能會在C代碼中執行and步驟(請參見腳注); 但以下方法通常應該起作用:

unsigned int OV_TMP = 0xffefffff, scratch;
asm volatile("mfsr %0, $PSW\n\t"
             "and %0, %0, %1\n\t"
             "mtsr %0, $PSW"
             : "=&r"(scratch) : "r"(OV_TMP));

此處的“ =&r”約束條件是在讀取輸入操作數( %1 )之前先寫入輸出操作數( %0 )。


腳注:據我所知(不是很遠,我只做過一點點ppc組裝),無需將mfsrmtsr指令保持特定的距離,這與其他上的某些鎖定步驟序列不同處理器。 如果是這樣,我會寫更多這樣的東西:

 static inline unsigned int read_psw() { unsigned int result; asm volatile("mfsr %0, $PSW" : "=r"(result)); return result; } static inline void write_psw(unsigned int value) { asm volatile("mtsr %0, $PSW" :: "r"(value)); } #define PSW_FE0 0x00100000 /* this looks like it's FE0 anyway */ ... write_psw(read_psw() & ~PSW_FE0); /* some appropriate comment here */ 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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