2012-02-05 11 views
13

eaxebxなどにプログラムが起動すると(linux、elf)、そこに0が入っているか、何かがある可能性があります(私は何もしていないか、externライブラリを使用していますか?私のマシンでは本当にそうですが、asmプログラムを書くときにそのような動作を中継することはできますか?プログラム起動時のデフォルトのレジスタ状態(asm、linux)とは何ですか?

+1

通常の状況では、これらを明示的に初期化します。したがって、初期状態が何であるかは関係ありません。 – nobar

+0

私は実行可能ファイルにいくつかのバイトを保存しようとしていますが、これを避けることができれば、移動ゼロをeaxにしたくありません。 movlコマンドを使用すると、5バイトに変換されるため、1をeaxに入れる必要があります。だから私はmovbを使用して、1をalにしたい。結果は同じで、コマンドは2バイトに変換されます。私は3バイトの利得を得る。しかし、デフォルトではeaxにゼロがある場合にのみ実行できます。 –

+0

どのような状況下で、この量のコードが節約できますか?ちょうどそれらを初期化してください。 EAXの最上位ビットが問題でなければ、movb al、1で初期化できますが、スペースについて心配する必要はありません。 –

答えて

17

これは、プラットフォームごとにABIに依存します。 eaxebxについては、x86の場合を見てみましょう。 ABIは、プログラムロード時にレジスタ値のための任意のrequirementsを指定している場合fs/binfmt_elf.cload_elf_binary()内部回線#972、カーネル・チェックで:

/* 
* 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. 
*/ 

次にarch/xxx/include/elf.h各アーキテクチャのために定義されたマクロである、ELF_PLAT_INITを呼び出します。 x86のために、それはfollowingん:あなたのELFバイナリをLinux 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) 

だから、あなたはすべてのレジスタ値がゼロに等しいに数えることができます。しかし、あなたがすべきではありません。 :-)

+3

このゼロ化はまだ発生しますが(2015)、ABIでは必須ではありません。 (バジルの答えに対するCiroのコメントを参照)。 –

+1

また、動的リンクされた実行可能ファイルでは、 '_start'の前に動的リンカーが実行され、ABIによって許可されているようにレジスタにガベージが残っていることにも注意してください。静的にリンクされた実行可能ファイルのみが、実行が '_start'に達するとレジスタがゼロになります。 –

9

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

i386 ABIための同様の仕様がありますが、ARM ABIなど

ELFABI

5

のx86-64システムV ABIセクション3.4.1 "初期スタックとレジスタの状態"上のウィキペディアのページを参照してください。 (Basile linked to PDF):

  1. 第スタックへ点

    スタックポインタは がスタックの一部である最下位アドレスのバイトのアドレスを保持します。プロセスのエントリ

  2. %rdxそれがゼロ以外だ場合、アプリケーションは、atexitをして登録する必要が関数ポインタで並んで16バイトであることが保証されます。

    アプリケーションが

  3. %rbpに登録するべき機能ポインタが指定されていないが、ユーザーランドは、ベースフレームに設定しなければなりません。

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

  4. その他はすべて定義されていません。

Linuxの場合は、「LSB」と表示されます

+1

'%rdx'はNULLにすることができ、現在のLinuxでは、静的にリンクされた実行可能ファイルからの新鮮なプロセスで' 0'です。しかし動的リンカーは、動的リンクされた実行可能ファイルを実行するときに '_start'の前で実行されるので、'%rdx'に値を設定できます( 'gdb/bin/bash'に従って)。私は '_start'がそれをその時点で関数ポインタとして扱うことになっているかどうかは確かではありませんが、おそらくはyesです。 –

+0

i386 ABI(http://www.sco.com/developers/devspecs/abi386-4.pdf)は、対応する32ビットレジスタの要件が同じです: '%esp'、'%edx'、 '%ebp'それ以外はすべて定義されていません。 – pts

関連する問題