ฉันเข้าใจสแต็กหรือไม่? โปรดแก้ไขฉันด้วย

ฉันมีรหัสนี้เขียนใน c:

int main(){
  double x, y;
  int a, b, c;
  int *p;

และฉันมี:

sizeof(int)=4
sizeof(double)=8

โครงสร้างหน่วยความจำเป็นแบบนี้หรือเปล่า? รายละเอียดเพิ่มเติมในโหมดกราฟิก:

IN MEMORY:(whole memory)
  LE = Little Endian  (INTEL)
  BE = Big Endian     (MIPS)

                                                  ------------------
                                    0x00000000   |                  | ?
                                                  ------------------
                                         .                 .
                                         .                 .
                                         .                 .
                                                  ------------------
                                    0x0012ff60   |  64(LE)  00(BE)  | 
                                                  ------------------
                                                  ------------------
                                    0x0012ff61   |  ff(LE)  12(BE)  | 
                                                  ------------------
                                                  ------------------
                                    0x0012ff62   |  12(LE)  ff(BE)  | 
                                                  ------------------
                                                  ------------------
                                    0x0012ff63   |  00(LE)  64(BE)  | 
                                                  ------------------

                                                  ------------------
                                    0x0012ff64   | 00(LE)   00(BE)  |  c         if c = 256        (base10)
                                                  ------------------                c = 0x00000100 (base16)
                                                  ------------------
                                    0x0012ff65   | 01(LE)   00(BE)  |  c   0x0012ff64 points to c variable
                                                  ------------------       0x0012ff64 is a pointer
                                                  ------------------
                                    0x0012ff66   | 00(LE)   01(BE)  |  c
                                                  ------------------
                                                  ------------------
                                    0x0012ff67   | 00(LE)   00(BE)  |  c 
                                                  ------------------
                                                  ------------------
                                    0x0012ff68   |                  |  b
                                                  ------------------
                                                           .
                                                           .
                                                           .
                                                  ------------------
                                    0x0012ff6c   |                  |  a
                                                  ------------------
                                                           .
                                                           .
                                                           .
                                                  ------------------
                                    0x0012ff70   |                  |  y
                                                  ------------------
                                                  ------------------
                                    0x0012ff71   |                  |  y
                                                  ------------------  
                                                  ------------------
                                    0x0012ff72   |                  |  y
                                                  ------------------
                                                  ------------------
                                    0x0012ff73   |                  |  y
                                                  ------------------
                                                  ------------------
                                    0x0012ff74   |                  |  y
                                                  ------------------
                                                  ------------------
                                    0x0012ff75   |                  |  y
                                                  ------------------
                                                  ------------------
                                    0x0012ff76   |                  |  y
                                                  ------------------
                                                  ------------------
                                    0x0012ff77   |                  |  y
                                                  ------------------
                                                          .
                                                          .
                                                          .
                                                  ------------------
                                    0x0012ff78   |                  |  x
                                                  ------------------
                                                          .
                                                          .
                                                          .
                                                  ------------------
                                    0xfffffffff  |                  |  ?
                                                  ------------------

คำถามของฉัน: เมื่อเรา push sth ลงใน stack เราจะทำเช่นนี้หรือไม่ ป้อนคำอธิบายรูปภาพที่นี่

1) ฉันหมายถึงเราส่งข้อมูลที่ส่วนท้ายของสแต็กโดยมีค่าที่อยู่สูงกว่าใช่ไหม

2) หรือเราส่งข้อมูลที่ด้านบนของสแต็กโดยมีค่าที่อยู่ต่ำกว่า?

3) แต่ละสแต็กใช้ที่อยู่ของหน่วยความจำจำนวนเท่าใด มันขึ้นอยู่กับอะไร

ขอบคุณ


person MLSC    schedule 18.02.2014    source แหล่งที่มา
comment
การลงทะเบียนลดลงไม่ได้ชี้ไปที่ตัวชี้คำสั่ง return แต่ชี้ไปที่ ebp ของฟังก์ชันก่อนหน้า   -  person BlackBear    schedule 18.02.2014
comment
อย่าลืมว่าคอมไพเลอร์สามารถ (และอาจจะ) เก็บตัวแปรโลคัลไว้ในรีจิสเตอร์ - บางส่วนหรือทั้งหมดอาจไม่อยู่ในสแต็กเลย   -  person Brendan    schedule 18.02.2014
comment
โปรดทราบว่าแม้แต่ความหมายของการลงทะเบียน EBP ก็อาจขึ้นอยู่กับคอมไพเลอร์: เมื่อใช้การปรับให้เหมาะสม EBP อาจไม่ได้ใช้เลยด้วยซ้ำ ในกรณีส่วนใหญ่ สแตกบนเครื่อง x86 ทำงานเหมือนที่คุณเข้าใจ อย่างไรก็ตามใน x86 ข้อมูลทั้งหมดนั้นน้อยมาก!   -  person Martin Rosenau    schedule 18.02.2014


คำตอบ (1)


บนเครื่อง x86 หากคอมไพลเลอร์ไม่ได้ทำอะไรพิเศษ สแตกจะขยายลงมา บน push ตัวชี้สแต็กจะลดลงตามขนาดของการพุช และข้อมูล pushed จะไปยังที่อยู่ด้านล่างของสแต็ก

ใน pop ตัวชี้สแต็กจะเพิ่มขึ้นตามขนาดของป๊อปอัป

ฉันไม่ได้แสดงความคิดเห็นเกี่ยวกับ MIPS แม้ว่าคุณจะพูดถึงมันในคำถามของคุณเพราะ:

  1. ฉันไม่รู้อะไรเกี่ยวกับสถาปัตยกรรม MIPS
  2. คำถามของคุณถูกแท็ก x86

เกี่ยวกับขนาดของแต่ละตัวแปรบนสแต็กนั้นขึ้นอยู่กับคอมไพเลอร์ 100% ดังนั้นฉันจึงไม่สามารถแสดงความคิดเห็นได้

person Nathan Fellman    schedule 18.02.2014
comment
โอเค ฉันไม่สนใจ MIPS จริงๆ ฉันเขียนโครงสร้างหน่วยความจำสำหรับ INTEL ถูกต้องหรือเปล่า ฉันมีคำถาม 3 ข้อในโพสต์ของฉัน และฉันจะขอบคุณหากคุณตอบโดยละเอียดเพิ่มเติม :) - person MLSC; 18.02.2014
comment
เขายังถามถึงขนาด(รวม)ด้วย(ผมคิดว่า) สิ่งนี้ถูกเลือกโดยคอมไพเลอร์ (และมักถูกจำกัดโดยระบบปฏิบัติการ) ใน gcc คุณสามารถเปลี่ยนได้โดยใช้ตัวเลือก --stack ค่าทั่วไปสำหรับเครื่องสมัยใหม่คือ 1 MB Linux สมัยใหม่มักมีขีดจำกัดอยู่ที่ 10 MB (ulimit -s) - person TypeIA; 18.02.2014
comment
@MortezaLSC: มันดูค่อนข้างโอเค นอกจากนี้ โปรดทราบว่าคุณถามคำถาม สอง เนื่องจาก (1) และ (2) เป็นสิ่งที่ตรงกันข้ามกัน - person Nathan Fellman; 18.02.2014
comment
@ Nathan Fellman ดังนั้นนี่จึงไม่สำคัญที่ด้านบนหรือจุดสิ้นสุดของสแต็ก .. จุดคือ the pushed data will go onto the lower addresses of the stack ขวา? - person MLSC; 18.02.2014
comment
ในความเข้าใจของฉันเกี่ยวกับหน่วยความจำ ฉันแสดงที่อยู่ตั้งแต่ 0x00000000 ที่ด้านบนถึง 0xfffffffff ที่ด้านล่าง..แต่รูปภาพนั้นเป็นอย่างอื่น...ใช่หรือไม่ :( - person MLSC; 18.02.2014
comment
@MortezaLSC: ที่อยู่จริงขึ้นอยู่กับค่าของการลงทะเบียน Stack Segment (SS) และค่าเริ่มต้นของ Stack Pointer (ESP) โดยทั่วไป คุณไม่สมควรที่จะตั้งสมมติฐานเกี่ยวกับค่าเหล่านี้ - person Nathan Fellman; 18.02.2014