0

私はクラス用のコンパイラを書いていますが、間接呼び出しを行うためのGNUの構文に固執しています。この単純なプログラムを考えてみましょう。

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

func:
  movl $42, %eax
  ret

結果のプログラムをコンパイルしgcc -m32 -O0て実行すると、セグメンテーション違反が発生します。誰かが正しく電話をかける方法を教えてもらえますか?

ありがとう。

ヴィンセント。

4

2 に答える 2

6

call指導自体は実際に良いです。:)

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

AT&T の即値オペランドには接頭辞$. コンパイル時の定数であるラベルの値はfunc、即値として使用でき、この場合はそれが必要です。したがって、に置き換えれmovl func, %eaxmovl $func, %eax大丈夫です。:)

ここでの使用leaは冗長です。もちろん動作しますが、funcはコンパイル時の定数であるため、実行時に把握するよりも、単純にコード内の即時型として配置する方がはるかに効果的です。

于 2012-04-16T00:24:46.260 に答える
-3

わかったと思います。問題を修正するlea代わりに使用。movllea が仮想アドレス変換を行っていると想像します。

于 2012-04-16T00:22:00.677 に答える