私はプログラミング言語の低レベルの操作がどのように機能するか、特にそれらがOS / CPUとどのように相互作用するかについて、より深く理解しようとしています。スタックオーバーフローのすべてのスタック/ヒープ関連スレッドのすべての回答を読んだことがあり、それらはすべて素晴らしいものです。しかし、まだ完全には理解していなかったことがあります。
有効なRustコードになる傾向がある疑似コードでこの関数を検討してください;-)
fn foo() {
let a = 1;
let b = 2;
let c = 3;
let d = 4;
// line X
doSomething(a, b);
doAnotherThing(c, d);
}
これは、スタックが行Xで次のように見えると想定する方法です。
Stack
a +-------------+
| 1 |
b +-------------+
| 2 |
c +-------------+
| 3 |
d +-------------+
| 4 |
+-------------+
今、私がスタックがどのように機能するかについて私が読んだすべては、それがLIFO規則に厳密に準拠しているということです(後入れ先出し)。.NET、Java、またはその他のプログラミング言語のスタックデータ型のように。
しかし、その場合、X行目以降はどうなりますか?明らかなので、次のことを我々の必要がで仕事にあるa
とb
、それはOS / CPUが(?)ポップアウトしなければならないことを意味するであろうd
と、c
最初に戻って取得するa
とb
。それが必要とするので、しかし、それは、足で自分自身を撮影するだろうc
し、d
次の行に。
では、裏で何が起きているのでしょうか?
別の関連する質問。次のような他の関数の1つへの参照を渡すことを検討してください。
fn foo() {
let a = 1;
let b = 2;
let c = 3;
let d = 4;
// line X
doSomething(&a, &b);
doAnotherThing(c, d);
}
私は物事を理解する方法から、これは中のパラメータがあることを意味するであろうdoSomething
本質的のように同じメモリアドレスを指しているa
とb
でfoo
。しかし、誰があり、その後、再び、この手段は、我々がされるまでスタックをポップアップしないa
とb
起こって。
この2つのケースでは、スタックがどのように正確に機能し、どのようにLIFOの規則に厳密に従っているかを完全には把握していません。
LIFO
スタックの最後でのみ要素を追加または削除でき、いつでも要素を読み取ったり変更したりできることを意味します。