มันดันอยู่ตรงไหน?
esp - 4. อย่างแม่นยำมากขึ้น:
esp ถูกลบด้วย 4
- ค่าจะถูกส่งไปที่
esp
pop ย้อนกลับสิ่งนี้
System V ABI บอกให้ Linux rspชี้ไปยังตำแหน่งสแต็กที่เหมาะสมเมื่อโปรแกรมเริ่มทำงาน: สถานะการลงทะเบียนเริ่มต้นคืออะไรเมื่อเปิดโปรแกรม (asm, linux) ซึ่งเป็นสิ่งที่คุณควรใช้เป็นประจำ
คุณจะกดลงทะเบียนได้อย่างไร?
ตัวอย่าง GNU GAS ขั้นต่ำ:
.data
/* .long takes 4 bytes each. */
val1:
/* Store bytes 0x 01 00 00 00 here. */
.long 1
val2:
/* 0x 02 00 00 00 */
.long 2
.text
/* Make esp point to the address of val2.
* Unusual, but totally possible. */
mov $val2, %esp
/* eax = 3 */
mov $3, %ea
push %eax
/*
Outcome:
- esp == val1
- val1 == 3
esp was changed to point to val1,
and then val1 was modified.
*/
pop %ebx
/*
Outcome:
- esp == &val2
- ebx == 3
Inverses push: ebx gets the value of val1 (first)
and then esp is increased back to point to val2.
*/
ข้างต้นใน GitHub พร้อมการยืนยันที่รันได้
เหตุใดจึงจำเป็น
มันเป็นความจริงว่าคำแนะนำเหล่านั้นสามารถดำเนินการได้อย่างง่ายดายผ่านทางmov, และaddsub
เหตุผลเหล่านี้มีอยู่นั่นคือชุดคำสั่งเหล่านั้นเกิดขึ้นบ่อยมากจน Intel ตัดสินใจจัดเตรียมคำแนะนำเหล่านี้ให้กับเรา
สาเหตุที่ชุดค่าผสมเหล่านี้เกิดขึ้นบ่อยมากก็คือทำให้ง่ายต่อการบันทึกและกู้คืนค่าของรีจิสเตอร์ไปยังหน่วยความจำชั่วคราวดังนั้นจึงไม่ถูกเขียนทับ
เพื่อทำความเข้าใจปัญหาให้ลองรวบรวมรหัส C ด้วยตนเอง
ปัญหาสำคัญคือการตัดสินใจว่าจะจัดเก็บตัวแปรแต่ละตัวไว้ที่ใด
ตามหลักการแล้วตัวแปรทั้งหมดจะพอดีกับรีจิสเตอร์ซึ่งเป็นหน่วยความจำที่เร็วที่สุดในการเข้าถึง (ปัจจุบันเร็วกว่า RAM ประมาณ100เท่า)
แต่แน่นอนว่าเราสามารถมีตัวแปรได้มากกว่ารีจิสเตอร์โดยเฉพาะสำหรับอาร์กิวเมนต์ของฟังก์ชันที่ซ้อนกันดังนั้นทางออกเดียวคือการเขียนลงในหน่วยความจำ
เราสามารถเขียนไปยังที่อยู่หน่วยความจำใด ๆ ก็ได้ แต่เนื่องจากตัวแปรภายในและอาร์กิวเมนต์ของการเรียกใช้ฟังก์ชันและการส่งคืนนั้นพอดีกับรูปแบบสแต็กที่ดีซึ่งป้องกันการแตกกระจายของหน่วยความจำนั่นจึงเป็นวิธีที่ดีที่สุดในการจัดการกับมัน เปรียบเทียบกับความบ้าคลั่งของการเขียนตัวจัดสรรฮีป
จากนั้นเราให้คอมไพเลอร์ปรับแต่งการจัดสรรรีจิสเตอร์ให้เหมาะสมที่สุดเนื่องจาก NP นั้นสมบูรณ์และเป็นส่วนที่ยากที่สุดในการเขียนคอมไพเลอร์ ปัญหานี้จะเรียกว่าการจัดสรรลงทะเบียนและมันก็เป็นไป isomorphic กราฟสี
เมื่อจัดสรรคอมไพเลอร์จะถูกบังคับให้สิ่งที่เก็บไว้ในหน่วยความจำแทนเพียงลงทะเบียนที่เป็นที่รู้จักกันการรั่วไหล
สิ่งนี้ทำให้คำสั่งโปรเซสเซอร์ตัวเดียวเดือดหรือซับซ้อนกว่านี้หรือไม่?
สิ่งที่เรารู้แน่นอนก็คือ Intel จัดทำเอกสาร a pushและpopคำสั่งดังนั้นจึงเป็นคำสั่งเดียวในแง่นั้น
ภายในสามารถขยายเป็นไมโครโค้ดได้หลายตัวตัวหนึ่งต้องปรับเปลี่ยนespและอีกอันใช้ทำหน่วยความจำ IO และใช้เวลาหลายรอบ
แต่ก็เป็นไปได้เช่นกันว่า single pushจะเร็วกว่าคำสั่งอื่น ๆ ที่ใช้ร่วมกันเนื่องจากมีความเฉพาะเจาะจงมากกว่า
สิ่งนี้ส่วนใหญ่เป็นเอกสารที่ไม่มี (der):
b,w,lหรือqเพื่อแสดงขนาดของหน่วยความจำที่ถูกครอบงำ เช่นpushl %eaxและpopl %eax