據我了解,堆疊變數是使用堆疊幀指標的絕對偏移量存盤的。但是這些變數以后是如何解決的呢?考慮以下代碼:
#include <iostream>
int main()
{
int a = 0;
int b = 1;
int c = 2;
std::cout << b << std::endl;
}
編譯器如何知道在哪里找到b?它是否將其偏移量存盤到堆??堆疊幀指標?如果是這樣,這些資訊存盤在哪里?這是否意味著int需要存盤超過 4 個位元組?
uj5u.com熱心網友回復:
堆疊變數的位置(相對于堆疊指標)是一個編譯時常量。編譯器總是知道自函式開始以來它被推入堆疊的數量,因此知道其中任何一個在堆疊幀中的相對位置。(除非您使用alloca或 VLA 1。)
在 x86 上,這通常是通過相對于ebporesp暫存器尋址來實作的,這些暫存器通常用于表示堆疊幀的“開始”和“結束”。偏移量本身不需要存盤在任何地方,因為它們作為尋址方案的一部分內置在指令中。
請注意,區域變數并不總是存盤在堆疊中。
編譯器可以自由地將它們放在任何它想要的地方,只要它表現得好像它是在堆疊上分配的。
特別是,像整數這樣的小物件可能會在其整個生命周期內(或直到編譯器被迫將它們溢位到堆疊上)簡單地留在暫存器中,常量可能存盤在只讀記憶體中,或者任何其他優化編譯器認為合適。
腳注 1:在使用 alloca 或 VLA 的函式中,即使在優化的構建中,編譯器也會使用單獨的暫存器(如 x86-64 中的 RBP)作為“幀指標”,并且地址相對于幀指標的區域變數,而不是堆疊指標。命名 C 變數的數量在編譯時是已知的,因此它們可以位于堆疊幀的頂部,其中從它們到幀指標的偏移量是恒定的。多個 VLA 可以像 alloca 一樣作為指向分配空間的指標作業。(這是一種典型的實施策略)。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/511278.html
標籤:C 变量记忆堆堆栈帧
下一篇:從函式中獲取新變數
