2

glibc-2.13-1を使用して、64 ビットの Debian 4.7.2-5 Linuxシステムを実行しています。いくつかの関数呼び出しのアセンブリ コードを検索しているときに、次のようなものを見つけました。libc.a

file format elf64-x86-64

Disassembly of section .text:

0000000000000000 <sync>:
   0:   b9 a2 00 00 00        mov    eax,0xa2
   5:   0f 05                 syscall
   7:   48 3d 01 f0 ff ff     cmp    rax,0xfffffffffffff001
   d:   0f 83 00 00 00 00     jae    13 <sync+0x13>
  13:   c3                    ret

これが何をしているのか少し混乱しています。mov eax,0xa2これが64ビットマシンである場合、レジスタが使用されないのはなぜですかrax(syscallはどのシステムコールを行うべきかをどのように知るのですか)要するに、これらの 5 行のコードは何をするのでしょうか?

4

2 に答える 2

5

0xa2 はシステムコール番号です。syscall命令自体には情報が含まれていないため、カーネルはそれを使用して、実行する実際の機能を決定します。

rax、慣れます。昔からの伝統をeax引き継ぐために、 は の下位 32 ビットのエイリアスですrax。ただし、x64 アーキテクチャにはあまり知られていない癖が 1 つあります。下位 32 ビット部分を変更すると、上位 32 ビットがゼロになります。したがって、エンコーディングが短いことを除いて、実際mov eax, 0xa2には と同等です。mov rax, 0xa2NASM またはas -O2は、その最適化も行います。

最後の 3 つの命令は、エラー処理を実行します。%raxが -1 から -4095 の間の場合 Linux システム コールのシステムコールがエラーを返したことを意味します。元のソースでの表示は次のとおりです。

cmpq $-4095, %rax    /* Check %rax for error.  */
jae __syscall_error  /* Branch forward if it failed.  */
ret                  /* Return to caller.  */

再配置可能オブジェクトを逆アセンブルしているため、 の間違ったターゲットが表示jaeされます。最終リンク時にパッチが適用されるため、再配置可能フィールドは 0 に設定されています。

再配置ターゲットを表示するには、コマンド ラインにスイッチを追加-robjdumpします。

0000000000000000 <sync>:
   0:   b8 a2 00 00 00          mov    $0xa2,%eax
   5:   0f 05                   syscall 
   7:   48 3d 01 f0 ff ff       cmp    $0xfffffffffffff001,%rax
   d:   0f 83 00 00 00 00       jae    13 <sync+0x13>
                        f: R_X86_64_PC32        __syscall_error-0x4
  13:   c3                      retq   

fジャンプ先が になるように、オフセットのバイトにパッチが適用される ことがわかります__syscall_error

syscall の詳細については、https: //cs.lmu.edu/~ray/notes/syscalls/ を参照してください。Linux システム コールの決定版ガイドのブログ記事
も参照してください。

于 2013-03-19T15:51:03.593 に答える
1

mov eax,0xa2raxゼロなどの 32 ビット汎用レジスタを変更するeaxと、対応する 64 ビット レジスタ (この場合は ) の上位 32 ビットが常に変更されるため、全体を設定するには で十分raxです。

syscall 番号a2はです。Linux x86-64 syscall のリストについてはsync、を参照してください (Linux ソースがインストールされているディレクトリに置き換えてください)。/usr/src/linux/usr/include/asm/unistd_64.h/usr/src/linux/

全体として、これらの行は、これらの命令の前に既に定義されているファイルを開き、syscall(in rax)の戻り値を と比較します。すると0xfffffffffffff001、少し奇妙な0f 83 00 00 00 00 jae 13ことがあります。次の命令への条件付きジャンプです。

于 2013-03-19T15:50:56.103 に答える