2012-04-15 10 views
0

私はクラス用のコンパイラを作成していますが、間接呼び出しを行うGNUの構文に慣れています。アセンブラで間接呼び出しを行う

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

func: 
    movl $42, %eax 
    ret 

gcc -m32 -O0してコンパイルし、結果のプログラムを実行している私にセグメンテーションフォールトを与える:この単純なプログラムは考えてみましょう。誰かが正しくコールを行う方法を教えてもらえますか?

ありがとうございました。

Vincent。

+0

関連質問:http://stackoverflow.com/questions/1897401/gnu-assembler-get-address-of-label-variable-intel-syntax – msandiford

答えて

-2

私はそれを持っていると思う。 movlの代わりにleaを使用すると問題が解決しました。私はleaが仮想アドレス変換をしていると思います。

+1

ナンセンス。これは仮想アドレスとは関係ありません。 'lea'はラベルfuncの実効アドレスをeaxにロードしますが、movは' mov $ 42、%eax'のオペコードであるfuncにラベルの内容をロードし、アドレスとして解釈されても意味をなさない。 – hirschhornsalz

5

call命令自体は実際には良いです。 :)

あなたの問題は、AT & T構文がどのように機能するのか忘れているようです。 movl func, %eaxでここでやっていることは、ラベルfuncのアドレスからeaxレジスタへのdwordをコピーしています。基本的にeaxは、実際の関数コードの最初の4バイトで終了します。

AT & Tの即値オペランドの先頭には、$が付いています。コンパイル時の定数であるfuncラベルの値は、即時に使用することができます。この場合、これが必要です。したがって、movl func, %eaxmovl $func, %eaxに置き換えても問題ありません。 :)

ここでleaを使用することは冗長です。もちろん動作しますが、funcはコンパイル時の定数なので、実行時にコードを理解するのではなく、コード内に即座に配置する方がはるかに効果的です。

関連する問題