2

GNUの以下の振る舞いを理解したいと思います。

OS Xでの次のテストプログラム(Apple cctools-822 / GNU as 1.38)

    .globl foo
    jmp foo
foo:
    ret

にエンコードされます

    00000000    e900000000    jmp         0x00000005
foo:
    00000005    c3            ret

Linux上のGNU(2.22としてのGNU)は

                                .global foo
    0000        E9FCFFFF        jmp 0x35 # foo
                FF
foo:
    0005        C3              ret

なぜ後者は(私にとって)奇妙なジャンプをするのですか?

さらに、明らかにこの魔法の0xfcffffffアドレスは、グローバルラベルへのジャンプごとに使用されます。

test2.s

    .globl foo
    jmp foo
    .globl bar
    jmp bar
    .globl baz
    jmp baz
foo:
    push $1
    ret
bar:
    push $2
    ret
baz:
    push $3
    ret

LinuxのようにGNUで生成します(GNUは2.22として)

                        .globl foo
    0000    E9FCFFFF    jmp foo
            FF
                        .globl bar
    0005    E9FCFFFF    jmp bar
            FF
                        .globl baz
    000a    E9FCFFFF    jmp baz
            FF
foo:
    000f    6A01        push $1
    0011    C3          ret
bar:
    0012    6A02        push $2
    0014    C3          ret
baz:
    0015    6A03        push $3
    0017    C3          ret

誰かがこの種の行動を説明できますか?

4

2 に答える 2

2

これは単なる別のタイプの再配置エントリ (R_386_PC32) です。

心配する必要はありません。リンカが正しいアドレスを挿入します。

たとえば、の-rオプションを追加すると、再配置エントリが表示されます。objdump

objdump -Dr test2.o

0xfffffffc = -4x86 はリトル エンディアンであるため、値は次のとおりであることに注意してください。

この質問も参照してください。

于 2012-06-11T12:54:00.030 に答える
1

実行可能ファイルではなくオブジェクトを逆アセンブルしていると思いますか? これは、すべてのツールチェーン、好みの前にオブジェクトにコンパイルするすべての言語で非常に一般的です。リンカーは...オブジェクトをリンクし、グローバルをリンクし、関数名、変数などをリンクします。リンク段階まで、自分がどのアドレス空間にいるのか、変数名を知る方法がないため、依存するローカルもあります命令セットとリーチの長さ、およびグローバルはリンク時まで解決できないため、オブジェクトには命令の代わりに何らかのフィラーデータが配置され、おそらく奇妙な方法で逆アセンブルされます。

于 2012-06-11T14:18:11.960 に答える