2015-04-02 37 views
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 

模式。

+0

如今,編譯器傾向於調整堆棧指針每個函數只有一次,不會推動和彈出所有的時間。這似乎在現代硬件上執行得更好(例如重新指令重新排序),並且釋放了一個額外的寄存器(* BP寄存器)。 – 2015-04-02 20:06:34

+0

謝謝。將地址%esp + 16放在堆棧頂部時,我仍然不明白代碼在做什麼。我認爲%esp在函數調用之前會指向函數參數,但這是%esp + 4.它指向什麼? – Russell 2015-04-03 16:35:51

+0

我認爲這相當於存儲基指針。由於從不使用* BP寄存器,因此提供了堆棧幀庫的一個副本。但這是未經優化的代碼,因此可能不需要這樣做。再次嘗試優化,並使用包含實際函數調用的代碼。 – 2015-04-04 09:03:29

回答

1

[ESP + 4]指向proc條目的返回地址。
[ESP + xx]指PROC輸入PARAMS
[ESP - xx]儲備的地方局部變量

enter image description here