2
我使用CompCert並將其編譯這個函數被調用者初始化和清理序列做了什麼?
int main() { return 0; }
到
# File generated by CompCert 2.3pl2
# Command line: -S test2.c
.text
.align 16
.globl main
main:
.cfi_startproc
subl $12, %esp
.cfi_adjust_cfa_offset 12
leal 16(%esp), %edx
movl %edx, 0(%esp)
xorl %eax, %eax
addl $12, %esp
ret
.cfi_endproc
.type main, @function
.size main, . - main
請注意,這是AT & T語法。
這是幹什麼的?
我不熟悉subl,leal,movl模式。
我只看到了
push %ebp
movl %esp, %ebp
...
leave
模式。
如今,編譯器傾向於調整堆棧指針每個函數只有一次,不會推動和彈出所有的時間。這似乎在現代硬件上執行得更好(例如重新指令重新排序),並且釋放了一個額外的寄存器(* BP寄存器)。 – 2015-04-02 20:06:34
謝謝。將地址%esp + 16放在堆棧頂部時,我仍然不明白代碼在做什麼。我認爲%esp在函數調用之前會指向函數參數,但這是%esp + 4.它指向什麼? – Russell 2015-04-03 16:35:51
我認爲這相當於存儲基指針。由於從不使用* BP寄存器,因此提供了堆棧幀庫的一個副本。但這是未經優化的代碼,因此可能不需要這樣做。再次嘗試優化,並使用包含實際函數調用的代碼。 – 2015-04-04 09:03:29