16

以下のx86_64の非常に複雑なプログラムでgcc-Sを実行しました。

int main() {
    int x = 3;
    x = 5;
    return 0;
}

そして私が得たのは:

       .file   "main.c"
        .text
.globl main
        .type   main, @function
main:
.LFB0:
        .cfi_startproc
        pushq   %rbp
        .cfi_def_cfa_offset 16
        .cfi_offset 6, -16
        movq    %rsp, %rbp
        .cfi_def_cfa_register 6
        movl    $3, -4(%rbp)
        movl    $5, -4(%rbp)
        movl    $0, %eax
        leave
        .cfi_def_cfa 7, 8
        ret
        .cfi_endproc
.LFE0:
        .size   main, .-main
        .ident  "GCC: (GNU) 4.4.7 20120313 (Red Hat 4.4.7-3)"
        .section        .note.GNU-stack,"",@progbits

誰かが私が出力を理解するのを手伝ってくれるのか、それとも説明しているリンクを紹介してくれるのかと思っていました。具体的にはcfi ,LFB0,LFE0 , leaveどういう意味ですか?これらに関して私が見つけたのはこの投稿だけですが、それが何のためにあるのか完全には理解できませんでした。また、retこの場合はどうなりますか?__libc_start_main()どちらに戻ってくるのdo_exit()かと思いますが、それは正しいですか?

4

2 に答える 2

23

これらの.cfisomethingディレクティブにより、コンパイラーによって追加のデータが生成されます。このデータは、命令によって例外が発生したときにコールスタックをトラバースするのに役立ちます。そのため、例外ハンドラー(存在する場合)を見つけて正しく実行できます。コールスタック情報は、デバッグに役立ちます。このデータは、おそらく実行可能ファイルの別のセクションに入ります。コードの命令の間に挿入されません。

.LFsomething:おそらくその余分な例外関連データによって参照される通常のラベルです。

leaveおよびretはCPU命令です。

leaveと同等です:

movq    %rbp, %rsp
popq    %rbp

そしてそれはこれらの2つの命令の効果を元に戻します

pushq   %rbp
movq    %rsp, %rbp

から何かを引くことによってスタックにスペースを割り当てる命令rsp

ret関数から戻ります。スタックからリターンアドレスをポップし、そのアドレスにジャンプします。__libc_start_main()と呼ばれるものであればmain()、そこに戻ります。

于 2013-03-08T01:15:43.603 に答える
14
  1. .LFB0, .LFE0ローカルラベルに他なりません。

  2. .cfi_startproc各関数の開始時に使用され、関数の終了はによって発生し.cfi_endprocます。

    • これらのアセンブラディレクティブは、アセンブラがデバッグおよびスタックアンワインド情報を実行可能ファイルに入れるのに役立ちます。
  3. 命令は、leave呼び出し元の関数のスタックフレームを復元する作業を行うx86アセンブラ命令です。

そして最後に、ret指示の後、次のことが起こります。

  • %rip差出人住所が含まれています
  • %rspamd64で引数を渡すために使用される6つのレジスタ(%rdi、%rsi、%rdx、%rcx、%r8、%r9)に収まらない呼び出し元によってプッシュされた引数を指します
  • 呼び出された関数の引数が破棄されている可能性があります
  • %rax戻り値を含む(または関数が無効な場合はごみ箱)(または、サイズが8バイトを超え16バイト未満の場合は戻り値%raxを含む1%rdx
  • %r10%r11ゴミ箱に入れられる可能性があります
  • %rbp、、、、、、には%rbx、呼び出し時のコンテンツが含まれている必要があります%r12%r13%r14%r15

追加情報はここ(SOの質問)ここ(標準のPDF)にあります。

または、32ビットの場合:

  • %eip差出人住所が含まれています
  • %esp呼び出し元によってプッシュされた引数を指す
  • 呼び出された関数の引数が破棄されている可能性があります
  • %eax戻り値が含まれています(または関数が無効な場合はゴミ箱)
  • %ecx%edxゴミ箱に入れられる可能性があります
  • %ebp、、、%ebxには%esi%edi呼び出し時のコンテンツが含まれている必要があります
于 2013-03-08T01:14:59.610 に答える