彙編

2012-04-15 97 views
0

使間接調用我正在寫的一類編譯器,和我卡在GNU的語法做間接調用。考慮這個簡單的程序:彙編

.text 
.globl main 
main: 
    movl func, %eax 
    call *%eax 
    ret 

func: 
    movl $42, %eax 
    ret 

編譯與gcc -m32 -O0和運行得到的程序給我一個分段錯誤。任何人都可以告訴我如何正確地進行呼叫嗎?

謝謝。

文森特。

+0

相關問題:http://stackoverflow.com/questions/1897401/gnu-assembler-get-address-of-label-variable-intel-syntax – msandiford 2012-04-16 00:43:43

回答

-2

我想我得到了它;用lea代替movl修復了這個問題;我認爲lea會進行虛擬地址轉換。

+1

廢話。這與虛擬地址無關。 'lea'將標籤func的有效地址加載到eax中,而mov將標籤的內容加載到'mov $ 42,%eax'的操作碼func,如果解釋爲地址,則沒有任何意義。 – hirschhornsalz 2012-04-16 07:56:58

5

call指令本身其實是不錯的。 :)

你的問題是,你似乎忘記了如何AT & T語法的作品。你在做什麼在這裏與movl func, %eax是複製從標籤func的地址的DWORD到eax寄存器。本質上,eax以您的函數的實際代碼的前4個字節結束。

AT & T中的立即操作數以前綴$爲前綴。作爲編譯時常量的func標籤的值可以用作立即數,在這種情況下這就是您想要的值。因此,請將movl func, %eax替換爲movl $func, %eax,您就會沒事的。 :)

使用lea這裏是多餘的。它當然會起作用,但由於func是一個編譯時常量,所以將它作爲一個直接代碼放在代碼中,而不是在運行時計算出來會更加有效。