これは、各プラットフォームの ABI に完全に依存します。 eax
に言及してから そして ebx
x86 の場合を見てみましょう。 fs/binfmt_elf.c
で 行 #972、load_elf_binary()
内 、カーネルは、プログラムのロード時にABIがレジスタ値の要件を指定しているかどうかをチェックします:
/*
* 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 をフックします。
Linux 上の AMD64 または x86-64 システム (64 ビット) の場合、x86-64 ABI はレジスタの初期内容を定義します。
i386 ABI、ARM ABI などにも同様の仕様があります。
ELF と ABI に関するウィキペディアのページを参照してください
x86-64 System V ABI
3.4.1「初期スタックと登録状態」(この PDF バージョンにリンクされている Basile):
<オール>
%rsp
スタックを指す
スタック ポインタは、スタックの一部であるアドレスが最も低いバイトのアドレスを保持します。プロセスの入り口で 16 バイト アラインされることが保証されます
%rdx
0 以外の場合、アプリケーションが atexit に登録する必要がある関数ポインター。
アプリケーションが登録する関数ポインタ
%rbp
は指定されていませんが、ユーザーランドはそれをベース フレームに設定する必要があります。
このレジスタの内容は、プロセスの初期化時に指定されませんが、ユーザー コードは、フレーム ポインターをゼロに設定して、最も深いスタック フレームをマークする必要があります。
他のすべては未定義です。
Linux は、LSB がそう言っている「ので」それに従います。