簡體   English   中英

為什么后續的Rust變量增加堆棧指針而不是減少堆棧指針?

[英]Why do subsequent Rust variables increment the stack pointer instead of decrementing it?

我覺得奇怪的是,當您在Rust中創建靜態分配的變量時,似乎隨着堆棧指針的增加而增加。 我知道不是這種情況,因為堆棧指針隨着分配的內存而減少。

如果要在C中做同樣的事情,我會發現隨着創建更多變量,堆棧指針會減少。

為什么這樣呢? Rust編譯器是否從下至上而不是從上至下分配這些?

fn main() {
    let i1 = 1;
    let i2 = 1;
    let i3 = 1;
    println!("i1 : {:?}", &i1 as *const i32);
    println!("i2 : {:?}", &i2 as *const i32);
    println!("i3 : {:?}", &i3 as *const i32);
}

當我運行該程序時,我收到以下消息:

i1 : 0x9f4f99fb24
i2 : 0x9f4f99fb28
i3 : 0x9f4f99fb2c

如果我使用C,我將得到:

i1 : 0x9f4f99fb2c
i2 : 0x9f4f99fb28
i3 : 0x9f4f99fb24

將堆棧視為功能堆棧幀序列,而不是可變地址序列。 不管堆棧增長的方向如何,它都會以整個堆棧幀的增量增長,每個堆棧幀的大小各不相同。

函數的堆棧框架的布局具有將變量綁定到的固定位置,類似於結構,但是不能保證框架內綁定的確切順序。 如果可以使該功能使用不同的布局更有效地利用空間,則可能會做到。 例如:

fn main() {
    let i1: i32 = 1;
    let i2: i64 = 2;
    let i3: i32 = 3;
    println!("i1 : {:?}", &i1 as *const i32);
    println!("i2 : {:?}", &i2 as *const i64);
    println!("i3 : {:?}", &i3 as *const i32);
}

// i1 : 0x7fff4b9271fc
// i2 : 0x7fff4b927200
// i3 : 0x7fff4b92720c

在此, i3 i2 之前存儲。 i64需要與64位的倍數對齊,因此將兩個i32存儲在一起而不是i32是更緊湊的。 這不會發生在調試版本中,編譯器也可以選擇存儲i3先用同樣的效果,所以我們不能和不應該依賴於這種排序。

也有可能出於任何其他優化原因(例如緩存訪問效率)對變量進行重新排序。


要查看堆棧確實向下增長,請考慮一個具有多個功能的示例:

fn main() {
    let i1 = 1;
    println!("i1 : {:?}", &i1 as *const i32);

    another();
}

#[inline(never)]
fn another() {
    let i2 = 2;
    println!("i2 : {:?}", &i2 as *const i32);
}

// i1 : 0x7fffc7601fbc
// i2 : 0x7fffc7601f5c

anothermain調用,因此其堆棧幀具有較低的地址。 注意,我不得不強制編譯器不要內聯函數,否則組合的布局將是任意的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM