21

プログラムの起動時 (linux、elf) - 、 などにゼロがeaxありebxますか、それとも何かある可能性がありますか (私は呼び出しを行っていないか、extern ライブラリを使用していません)? 私のマシンでは本当にそうです.asmプログラムを書くときにそのような振る舞いを中継できますか?

4

3 に答える 3

23

これは、各プラットフォームの ABI に完全に依存します。あなたが言及eaxしたのでebx、x86の場合はどうなるか見てみましょう。fs/binfmt_elf.c行番号 972 の内部で、カーネルはプログラムのロード時に ABI がレジスタ値の要件load_elf_binary()を指定しているかどうかをチェックします。

/*
 * The ABI may specify that certain registers be set up in special
 * ways (on i386 %edx is the address of a DT_FINI function, for
 * example.  In addition, it may also specify (eg, PowerPC64 ELF)
 * that the e_entry field is the address of the function descriptor
 * for the startup routine, rather than the address of the startup
 * routine itself.  This macro performs whatever initialization to
 * the regs structure is required as well as any relocations to the
 * function descriptor entries when executing dynamically links apps.
 */

ELF_PLAT_INIT次に、 のアーキテクチャごとに定義されたマクロである を呼び出しますarch/xxx/include/elf.h。x86 の場合、のことを行います。

#define ELF_PLAT_INIT(_r, load_addr)        \
    do {                                    \
        _r->bx = 0; _r->cx = 0; _r->dx = 0; \
        _r->si = 0; _r->di = 0; _r->bp = 0; \
        _r->ax = 0;                         \
    } while (0)

そのため、静的にリンクされた ELF バイナリが Linux x86 にロードされると、すべてのレジスタ値がゼロに等しいと期待できます。ただし、そうするべきだというわけではありません。:-)


動的リンク

動的にリンクされたバイナリを実行すると、実行が_start(ELF エントリ ポイント) に到達する前に、プロセス内で動的リンカー コードが実際に実行されることに注意してください。これにより、ABI で許可されているように、レジスタにガベージが残る可能性があります。 もちろん、スタック ポインター ESP/RSP とatexitフック EDX/RDX を除きます。

于 2012-02-05T07:53:49.087 に答える
12

Linux上のAMD64またはx86-64システム(64ビット)の場合、x86-64ABIはレジスタの初期コンテンツを定義します。

i386 ABIARMABIなどにも同様の仕様があります。

ELFABIのウィキペディアのページを参照してください

于 2012-02-05T08:47:54.303 に答える
9

x86-64 System V ABI

3.4.1「初期スタックと登録状態」(BasileはこのPDF版にリンクされています):

  1. %rspスタックを指す

    スタック ポインタは、スタックの一部である最小アドレスのバイトのアドレスを保持します。プロセス エントリで 16 バイト アラインされることが保証されます。

  2. %rdxゼロ以外の場合、アプリケーションが atexit に登録する必要がある関数ポインター。

    アプリケーションが登録する関数ポインタ

  3. %rbpは指定されていませんが、ユーザーランドはそれをベース フレームに設定する必要があります。

    このレジスタの内容は、プロセスの初期化時に指定されていませんが、ユーザー コードは、フレーム ポインターをゼロに設定して、最も深いスタック フレームをマークする必要があります。

  4. 他のすべては未定義です。

Linuxは、 LSBがそう言っている「ので」それに従います。

于 2015-10-06T09:56:33.670 に答える