簡體   English   中英

理解 gcc -S 輸出

[英]Understanding gcc -S output

我在 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() ,對嗎?

這些.cfisomething指令會導致編譯器生成額外的數據。 當指令導致異常時,此數據有助於遍歷調用堆棧,因此可以找到並正確執行異常處理程序(如果有)。 調用堆棧信息對於調試很有用。 該數據很可能進入可執行文件的單獨部分。 它不會插入您的代碼指令之間。

.LFsomething:只是可能被額外的異常相關數據引用的常規標簽。

leaveret是 CPU 指令。

leave相當於:

movq    %rbp, %rsp
popq    %rbp

它會撤銷這兩條指令的效果

pushq   %rbp
movq    %rsp, %rbp

和通過從rsp減去一些東西來分配堆棧空間的指令。

ret從函數返回。 它從堆棧中彈出返回地址並跳轉到該地址。 如果是__libc_start_main()調用了main() ,那么它會返回那里。

  1. .LFB0, .LFE0是本地標簽。

  2. .cfi_startproc用於每個函數的開頭,函數的結尾是.cfi_endproc

    • 這些匯編器指令幫助匯編器將調試和堆棧展開信息放入可執行文件中。
  3. leave指令是一條 x86 匯編指令,它負責恢復調用函數的堆棧幀。

最后在ret指令之后,發生了以下事情:

  • %rip包含返回地址
  • %rsp指向調用者推送的參數,這些參數不適合用於在 amd64 上傳遞參數的六個寄存器(%rdi、%rsi、%rdx、%rcx、%r8、%r9)
  • 被調用的函數可能有垃圾參數
  • %rax包含返回值(如果函數為 void,則為垃圾)(或%rax%rdx包含返回值,如果其大小大於 8 字節但 <=16 字節1
  • %r10 , %r11可能被丟棄
  • %rbp , %rbx , %r12 , %r13 , %r14 , %r15必須包含調用時的內容

可以在此處(SO 問題)此處(標准 PDF)找到其他信息。

或者,在 32 位上:

  • %eip包含返回地址
  • %esp指向調用者推送的參數
  • 被調用的函數可能有垃圾參數
  • %eax包含返回值(如果函數為空則為垃圾)
  • %ecx , %edx可能被丟棄
  • %ebp , %ebx , %esi , %edi必須包含調用時的內容

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM