函數的調用和棧是分不開的。
棧幀/活動記錄
當發生函數調用時,會將函數運行需要的信息全部壓入棧中,這常常被稱為棧幀(Stack Frame)或活動記錄(Activate Record)。
活動記錄一般包含以下幾個方面:
1.函數的返回地址,也就是函數執行完成后從哪里開始執行后面的代碼。
```
int a, b, c;
func(1, 2);
c = a + b;
```
func()函數執行完畢后,會繼續執行c = a + b;
語句,那么返回地址就是該語句在內存中的地址。
2.參數和局部變量。有些編譯器會通過寄存器來傳遞參數,而不是將參數壓入棧中。
3.編譯器自動生成的臨時數據。例如,當函數返回值的長度較大時,會先將返回值壓入棧中,然后再交給函數調用者。
當返回值的長度較小(char, int, long等)時,不會被壓入棧中,而是先將返回值放入寄存器,再傳遞給函數調用者。
4.一些需要保存的寄存器,例如ebp,ebx等。之所以保存寄存器的值,是為了在函數退出時能夠恢復到函數調用之前的場景,繼續執行上層函數。
關於數據的定位
esp的值是變化的;ebp的值是固定的,數據相對ebp的偏移也是固定的,ebp + 偏移量 = 數據地址
。