簡體   English   中英

GCC內聯匯編中的標簽

[英]Labels in GCC inline assembly

在我正在進行的GCC內聯匯編實驗中,我遇到了一個關於標簽和內聯代碼的新問題。

考慮以下簡單的跳轉:

__asm__
(
    "jmp out;"
    "out:;"
    :
    :
);

這確實沒有什么不同之處跳轉到out標簽。 這樣,這段代碼編譯得很好。 但是如果你把它放在一個函數中,然后用優化標志進行編譯,編譯器就會抱怨:“錯誤:符號'out'已經被定義了”。

似乎正在發生的事情是編譯器每次內聯函數時都會重復此匯編代碼。 這使標簽out得到復制,導致多out的標簽。

那么,我該如何解決這個問題呢? 在內聯裝配中是否真的不可能使用標簽? 關於GCC內聯匯編的教程提到:

因此,您可以將匯編放入CPP宏和內聯C函數中,因此任何人都可以將其用作任何C函數/宏。 內聯函數非常類似於宏,但有時使用起來更干凈。 請注意,在所有這些情況下,代碼將被復制,因此只應在該asm代碼中定義本地標簽 (1:樣式)。

我試圖找到有關這些“本地標簽”的更多信息,但似乎找不到與內聯匯編有關的任何內容。 看起來教程是說本地標簽是一個數字,后跟冒號(如1: :),所以我嘗試使用這樣的標簽。 有趣的是,代碼已編譯,但在運行時它只是觸發了分段錯誤。 嗯...

那么任何建議,提示,答案......?

本地標簽的聲明確實是一個數字后跟冒號。 但是對本地標簽的引用需要后綴為fb ,具體取決於您是要向前還是向后 - 即1f指向前進方向的下一個1:標簽。

因此將標簽聲明為1:是正確的; 但要引用它,你需要說jmp 1f (因為你在這種情況下是向前跳)。

嗯,這個問題並沒有變得更年輕,但還有另外兩個有趣的解決方案。

1)此示例使用%=。 匯編程序模板中的%=被替換為“對整個編譯中的每個insn唯一的數字。這對於制作在給定insn中多次引用的本地標簽很有用。” 請注意,要使用%=,您(顯然)必須至少有一個輸入(盡管您可能不必實際使用它)。

int a = 3;
asm (
    "test %0\n\t"
    "jnz to_here%=\n\t"
    "jz to_there%=\n\t"
    "to_here%=:\n\t"
    "to_there%=:"
    ::"r" (a));

這輸出:

test %eax
jnz to_here14
jz to_there14
to_here14:
to_there14:

或者,您可以使用asm goto(我認為在v4.5中添加)。 這實際上允許您跳轉到c標簽而不僅僅是asm標簽:

asm goto ("jmp %l0\n"
 : /* no output */
 : /* no input */
 : /* no clobber */
 : gofurther);

printf("Didn't jump\n");

// c label:
gofurther:
printf("Jumped\n");

暫無
暫無

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

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