ฉันพยายามทำความเข้าใจให้ลึกซึ้งยิ่งขึ้นว่าการทำงานของภาษาโปรแกรมระดับต่ำทำงานอย่างไรและโดยเฉพาะอย่างยิ่งวิธีที่พวกเขาโต้ตอบกับ OS / CPU ฉันอาจอ่านทุกคำตอบในทุกเธรดที่เกี่ยวข้องกับสแต็ก / ฮีปที่นี่ใน Stack Overflow และพวกเขาทั้งหมดยอดเยี่ยม แต่ยังมีสิ่งหนึ่งที่ฉันยังไม่เข้าใจ
พิจารณาฟังก์ชันนี้ในรหัสหลอกซึ่งมีแนวโน้มที่จะเป็นรหัสสนิมที่ถูกต้อง ;-)
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
ในบรรทัดถัดไป
ฉันสงสัยว่าเบื้องหลังเกิดอะไรขึ้นกันแน่ ?
อีกคำถามที่เกี่ยวข้อง พิจารณาว่าเราส่งการอ้างอิงไปยังฟังก์ชันอื่น ๆ เช่นนี้:
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
เกิดขึ้น
ทั้งสองกรณีทำให้ฉันคิดว่าฉันยังไม่เข้าใจอย่างถ่องแท้ว่าสแต็กทำงานอย่างไรและปฏิบัติตามกฎLIFOอย่างเคร่งครัดอย่างไร
LIFO
หมายความว่าคุณสามารถเพิ่มหรือลบองค์ประกอบที่ส่วนท้ายของสแต็กเท่านั้นและคุณสามารถอ่าน / เปลี่ยนแปลงองค์ประกอบใด ๆ ได้ตลอดเวลา