這是一個簡單的功能
#include <stdio.h>
int foo() {
int a = 3;
int b = 4;
int c = 5;
return a * b * c;
}
int main() {
int a = foo();
}
foo() 的程式集看起來像
foo:
push rbp
mov rbp, rsp
mov DWORD PTR [rbp-4], 3
mov DWORD PTR [rbp-8], 4
mov DWORD PTR [rbp-12], 5
mov eax, DWORD PTR [rbp-4]
imul eax, DWORD PTR [rbp-8]
imul eax, DWORD PTR [rbp-12]
pop rbp
ret
從 中可以看出rbp - N,內部堆疊框架正在被修改。那么,為什么沒有leaves 或add rsp, n?
uj5u.com熱心網友回復:
從堆疊指標不變的意義上說,它“沒有被修改”。由于我們從來沒有從入口處減去任何偏移量rsp,當然我們不應該在出口處添加任何偏移量。
并且leave簡單地等價于mov rsp, rbp ; pop rbp。我們確實包含pop rbp, 并且mov rsp, rbp將是多余的,因為如您所見,rsp并且rbp在代碼中的那一點仍然相等。
實際上,該函式將其區域變數存盤在堆疊中,而無需調整堆疊指標以為它們“騰出空間”,因此它們最終位于堆疊指標下方。這是合法的,因為 x86-64 SysV ABI 要求有一個紅色區域;不進行任何函式呼叫的代碼可以安全地使用堆疊指標下方的 128 個位元組。信號處理程式保證不會覆寫它。
為什么 x86-64 GCC 函式序言分配的堆疊比區域變數少?
x86-64 上的紅色區域到底在哪里?
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/472976.html
