1

GCCのオプションをテストするための小さなプログラムを作成しました。

int main()
{
    int a=0;
    __asm__("movl %0,%%ecx\n"
            "jmp jmpsection\n"
            "inc %%ecx\n"
            "jmpsection: movl $1,%%eax\n"
            "movl $0,%%ebx\n"
            "int $0x80\n"::"a"(a):"ecx","ebx");
}

var aを1に保つために、inc命令をスキップしてください。GCCにIP相対アドレス指定方式を使用してjmp命令を生成させたい。解決策を見つけるためにGCCマニュアルを検索しましたが、失敗しました。リプレイありがとうございます。

4

2 に答える 2

3

x86の場合、IP相対アドレス指定はロングモード(64ビット)でのみ可能であり、32ビットコードを記述しているようです。

編集:実際には、32ビットモードでは現在のIPを基準にしてジャンプすること可能であり、コンパイラーは実際に正しいコードを生成すると思います。生成されたアセンブリの関連部分を見てみましょう。

00000000 <main>:
  ...
  13:   eb 01                   jmp    16 <jmpsection>
  15:   41                      inc    %ecx

00000016 <jmpsection>:
  16:   b8 01 00 00 00          mov    $0x1,%eax
  ...

したがって、アドレス13の命令がアドレス16に直接ジャンプするように見えますが、実際にIP相対ジャンプです。マシンコードを見てください:

eb 01

ebjmpは、 8ビット変位のショートのオペコードです。01この変位です。この命令の結果はにジャンプし、IPが次に%eip + 0x01実行される命令を指すと、これはアドレス16にジャンプします。

于 2012-04-20T13:26:17.323 に答える
1

GCCでインラインアセンブリを使用する場合、アセンブリコードはアセンブラに直接渡されます。GCCのコマンドラインオプションは、アセンブリコードを変更しません。出力を確認することができます(-Sオプションを使用)。コンパイラオプションは、GCCがCコードからアセンブリを生成する方法のみを変更します。

したがって、コンパイラのマニュアルの代わりに、アセンブラのマニュアルを参照する必要があります。あなたの場合、GASはおそらくjmpオプションを指定する必要なしに短いPC相対コーディングを選択します。

于 2012-04-20T17:00:54.337 に答える