สแตกการโทรเริ่มที่ด้านล่างหรือด้านบน?


11

สแต็คเป็นสิ่งที่ซ้อนจากล่างขึ้นบน

ดังนั้นสแต็กการโทรจะเพิ่มไอเท็มใหม่บนสแต็กเมื่อเรียกใช้ฟังก์ชันโดยไอเท็มจะถูกลบออกจากสแต็กเมื่อแต่ละฟังก์ชันสิ้นสุดลงจนกว่าสแต็กจะว่างเปล่าจากนั้นโปรแกรมจะสิ้นสุด

หากข้อมูลด้านบนถูกต้องเหตุใดผู้คนจึงอ้างถึงการควบคุมการย้าย "up" ของ call stack? การควบคุมอย่างแน่นอนเลื่อนลงไปสแตกการโทรจนกว่าจะถึงด้านล่าง


เมื่อเรียกใช้ฟังก์ชันจะมีการเพิ่มรายการลงในด้านบนสุดของสแต็กและการควบคุมจะถูกส่งผ่านไปยังฟังก์ชันนั้น ดังนั้นการควบคุมจะย้ายจากรายการพื้นฐานในสแต็กไปยังรายการด้านบน - ขึ้น
treecoder

1
@greengit: นิพจน์ "up the call stack" ถูกใช้โดยมีข้อยกเว้นซึ่งการควบคุมจะย้ายไปในทางตรงกันข้าม
Michael Borgwardt

@MichaelBorgwardt: คุณถูกต้อง
treecoder

1
@MichaelBorgwardt: ฉันเห็นนิพจน์ "ข้อผิดพลาดเลื่อนขึ้นสายการโทร" แน่นอนว่าไม่ถูกต้อง
CJ7

3
ประตูของศัตรูลง
Jon

คำตอบ:


9

มีเหตุผลที่เป็นไปได้สองประการสำหรับการใช้งานนี้:

  • ในบริบทของข้อยกเว้นตัวควบคุมจะย้ายไปที่ฟังก์ชัน / เมธอดการเรียกและลำดับชั้นการโทรนี้มักจะมองเห็นได้ด้วยวิธีหลักด้านบนและการเรียกเมธอดที่สร้างลำดับชั้นลงโดยมีระดับนามธรรมลดลง ในลำดับชั้นนี้มีข้อยกเว้นเลื่อนขึ้น

  • สแต็คโปรแกรมจริงในแอปพลิเคชัน x86 ปกติกลับด้านคือมันขยายตัวลง คำแนะนำเกี่ยวกับรหัสเครื่อง PUSH / PUSHW / PUSHD จะลดตัวชี้สแต็ค สถาปัตยกรรมอื่น ๆ อาจแบ่งปันโมเดลนี้


แนวคิดจากบนลงล่างไม่ได้ขัดกับแนวคิดในชีวิตประจำวันของ "กองซ้อน" ที่เป็นกองรายการเริ่มต้นที่ด้านล่างใช่หรือไม่
CJ7

@CraigJ: ดังนั้นความจริงที่ว่าบิตของแต่ละไบต์ของเนื้อหาสแต็กจะถูกเก็บไว้ในชิปแยกต่างหาก ใครสน?
Michael Borgwardt

1

ทุกอย่างขึ้นอยู่กับคำจำกัดความของคำ; คุณหมายถึงอะไรอย่างแท้จริงด้วยคำว่า "top" และ "bottom" ในบริบทนี้รวมถึงการใช้งานระบบปฏิบัติการหรือสถาปัตยกรรมคอมพิวเตอร์

ฉันจำสิ่งต่อไปนี้เมื่อนานมาแล้วเมื่อฉันเขียนโปรแกรมบน Commodore 64 หน่วยความจำระหว่างที่อยู่ $ 0800 (2048) และ $ 9FFF (40959) ถูกสงวนไว้สำหรับโปรแกรมพื้นฐาน รหัสของโปรแกรม BASIC ของคุณถูกเก็บไว้เริ่มต้นจากที่อยู่ต่ำกว่า ($ 0800 เพิ่มขึ้นจากที่นั่น) สแต็กสำหรับการจัดเก็บตัวแปรและที่อยู่ที่ส่งกลับของรูทีนย่อยเริ่มต้นที่ด้านบน ($ 9FFF) ของช่วงนั้นและขยายไปสู่ที่อยู่ต่ำกว่า ในบริบทนี้มันมีเหตุผลที่จะเห็นสแต็คเพิ่มขึ้นและเมื่อคุณกลับมาจากรูทีนย่อยเฟรมสแต็คของรูทีนย่อยถูกยกเลิกโดยการเพิ่มตัวชี้สแต็คเพื่อเพิ่มว่าคุณกำลัง กลับมาจากรูทีนย่อย

ฉันไม่รู้ว่ามันทำงานอย่างไรกับโปรเซสเซอร์รุ่น Windows หรือ Intel x86 รุ่นใหม่ บางทีสแต็กอาจทำงานในลักษณะอื่น ๆ เช่นมันเติบโตจากที่อยู่ต่ำไปสู่ที่สูงขึ้น หากเป็นเช่นนั้นคุณอาจใช้คำว่า "top", "bottom" และ "up", "down" อย่างอื่น


0

ในการเรียกใช้ฟังก์ชันเช่น foo (6, x + 1) ...

  1. ประเมินการแสดงออกของพารามิเตอร์ที่เกิดขึ้นจริงเช่น x + 1 ในบริบทของผู้โทร
  2. จัดสรรหน่วยความจำสำหรับคนในท้องถิ่นของ foo () โดยการกด "โลคัลบล็อก" ที่เหมาะสมของหน่วยความจำลงบนรันไทม์ "call stack" เพื่อวัตถุประสงค์นี้โดยเฉพาะ สำหรับพารามิเตอร์ แต่ไม่ใช่ตัวแปรท้องถิ่นให้เก็บค่าจากขั้นตอน (1) ลงในสล็อตที่เหมาะสมในบล็อกโลคัลของ foo ()
  3. จัดเก็บที่อยู่ปัจจุบันของผู้โทรเพื่อดำเนินการ ("ที่อยู่ผู้ส่ง") และสลับการดำเนินการเป็น foo ()
  4. foo () เรียกใช้งานด้วยบล็อกโลคัลที่พร้อมใช้งานในตอนท้ายของ call stack
  5. เมื่อ foo () เสร็จสิ้นแล้วจะออกโดยการดึงคนในท้องถิ่นออกจากสแต็กและ "ส่งคืน" ไปยังผู้โทรโดยใช้ที่อยู่ผู้ส่งที่เก็บไว้ก่อนหน้านี้ ตอนนี้ผู้โทรเข้าอยู่ที่ท้ายสแต็กและสามารถดำเนินการต่อได้

อ้างอิง:

http://cslibrary.stanford.edu/102/PointersAndMemory.pdf (p15)


โปรดทราบว่านี่เป็นข้อกำหนดที่เฉพาะเจาะจงสำหรับการเรียก มีการเรียกประชุมที่อนุญาตให้ผู้โทรทำความสะอาดใช้อย่างน้อยที่สุดก็ลงทะเบียน ฯลฯ

0

ถ้าคุณคิดว่ากองซ้อนเป็นสิ่งที่อยู่ด้านล่างขึ้นมาเช่นกระบอกที่มีลูกเทนนิสอยู่ในนั้นภายใต้ความโน้มถ่วงตามปกติแล้วการควบคุมก็จะย้ายกองขึ้นไปตามที่เรียกว่าฟังก์ชั่น เมื่อฟังก์ชั่นสมบูรณ์แล้วตัวควบคุมจะเลื่อนลงมาในสแต็ก

หากคุณคิดว่ากองซ้อนเป็นสิ่งที่เรียงจากบนลงล่างเช่นเดียวกับกระบอกลูกเทนนิสเดียวกัน แต่มีแรงโน้มถ่วงกลับด้านการควบคุมจะเลื่อนลงกองซ้อนตามที่ฟังก์ชันถูกเรียกและเพิ่มกองซ้อนเมื่อฟังก์ชันเสร็จสมบูรณ์

สิ่งเหล่านี้เป็นเพียงแค่แบบจำลองในหัวของคุณและโดยพลการทั้งหมด คุณสามารถกำหนดแนวความคิดเป็นสิ่งที่เคียงข้างกันหากคุณต้องการ แต่อาจมีปัญหาในการสื่อสารกับผู้คน โดยส่วนตัวฉันคิดว่าถ้า A โทร B และ B เรียก C ว่า C เป็นด้านล่างของสแต็ค (กลับหัวความโน้มถ่วงจริง) และหากมีข้อยกเว้นเกิดขึ้นใน C คุณต้องการฟองข้อยกเว้นนั้น "ขึ้น" ถึง A ฉันคิดว่านี่อาจเป็น การใช้ภาษาทั่วไปมากขึ้นเพราะความรู้สึกคือ C ลึกและ A เป็นอันดับต้น ๆ ฟังก์ชั่นแรกนั้นให้ความสำคัญกับฉันมากยิ่งขึ้น

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.