2017-09-24 159 views
0

這是第一次我寫彙編代碼。 在第一個開始,我寫了

#include<stdio.h> 
int main(){ 
    int x,y; 
    asm("movl $2,%eax"); 
    asm volatile(
        "movl $1,%0\n\t" 
        "movl %0,%%ebx\n\t" 
        "leal 2(%%ebx,%%eax,$2),%1" 
        :"=m"(x),"=r"(y) 
        ); 
    printf("x is %d, y is %d\n",x,y); 
    return 0; 
} 

的GCC 5.4.0編譯器會發出錯誤信息:

test.c: Assembler messages: 
test.c:7: Error: bad or irreducible absolute expression 
test.c:7: Error: expecting scale factor of 1, 2, 4, or 8: got `$2' 

然後我改變了

"leal 2(%%ebx,%%eax,$2),%1" 

"leal 2(%%ebx,%%eax,2),%1" 

它是o ķ。但是,2美元不等於2?

+1

在此語法的數量必須是沒有$,這就是它只是如何定義的。通常情況下$意味着一個常量,但由於在尋址模式中除了特定的常量外沒有別的東西,所以它不會使用前綴來表示這是一個常量。 –

+1

僅供參考,不重挫告訴編譯器(帶撞約束)'%ebx'將導致不可預知的結果。 (好吧,如果你用'gcc -O2 -S'從編譯器中讀取最終的asm輸出結果是可以預測的)。請參閱https://stackoverflow.com/tags/inline-assembly/info –

回答

0

在AT & T語法中,美元符號$表示一個立即數操作數。例如,它區分

add 16,%eax 

add $16,%eax 

(在地址16增值eax)(添加16eax)。請注意,這與整數常量無關。你也可以同樣令狀

add foo,%eax 

add $foo,%eax 

其中foo是一些符號。 disp(base,index,scale)表示使用SIB尋址的存儲器操作數。每三塊在這種尋址模式有一個固定的目的,所以在與任何裝飾scale沒有意義的。畢竟,我們已經選擇了一種尋址模式,爲什麼在括號內應該有另一個操作數類型的指示器呢?請注意,寄存器名稱前面的%仍然是強制性的,因爲它將寄存器名稱與宏或符號名稱區分開來。