首先,C標準禁止採用宣佈爲register
的變量的地址,就像它對struct
中的位字段所做的那樣。
對於非註冊(「自動」)變量,簡短答案是肯定的。優化器的最簡單的策略是立即泄漏地址的變量。
「溢出」只是寄存器分配文獻中的一個術語,意思是「決定放在內存中而不是寄存器」。
一個複雜的優化器可以做一個別名分析並且仍然在寄存器中保存一個值,即使它的地址已被佔用。這是可能的,無論哪裏可以證明所產生的指針不可能被用來改變值。
另一個相關優化是生存分段。這允許一個變量被存儲在一個寄存器中,用於保存一個有用值(它的「活動範圍」)並在其他部分溢出的指令範圍的一部分。在這種情況下,溢出的部分將對應於指針可能使用來更改變量值的位置。例如:
x = 3;
... lots of computations involving x
if T {
// SPILL HERE, so store register holding x to memory
int *p = &x;
... lots of computations, perhaps using p to change x
*p = 2;
// DONE SPILL HERE, so reload register
... more code here not using p to change x.
}
else {
... lots of computations involving x.
}
此代碼的分配對於x的堆疊位置,但它加載到寄存器中的代碼的頂部,將其保持有除區域標記爲SPILL的侵略性優化器。該區域將被寄存器存儲器和匹配的寄存器負載所包圍。
我不清楚你問的是什麼。如果你正在討論函數參數,那麼它們都是通過堆棧來處理的。 – alex
一些調用約定使用堆棧,其他人使用寄存器或兩者的組合。它們並不都是由堆棧處理的,除非你正在討論特定的具有特定編譯器的架構上的特定調用約定。 –
我的意思是在一般意義上使用變量的地址。例如,我可以將地址打印到屏幕上。 –