[英]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:
只是可能被額外的異常相關數據引用的常規標簽。
leave
和ret
是 CPU 指令。
leave
相當於:
movq %rbp, %rsp
popq %rbp
它會撤銷這兩條指令的效果
pushq %rbp
movq %rsp, %rbp
和通過從rsp
減去一些東西來分配堆棧空間的指令。
ret
從函數返回。 它從堆棧中彈出返回地址並跳轉到該地址。 如果是__libc_start_main()
調用了main()
,那么它會返回那里。
.LFB0, .LFE0
是本地標簽。
.cfi_startproc
用於每個函數的開頭,函數的結尾是.cfi_endproc
。
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.