จุดประสงค์ของโซนสีแดงคืออะไร?


12

Red zone เป็นพื้นที่ขนาดคงที่ในหน่วยความจำเกินกว่าตัวชี้สแต็กที่ยังไม่ได้ "จัดสรร" คอมไพเลอร์สร้างแอสเซมบลีเพื่อเข้าถึงพื้นที่นั้นในฟังก์ชันใบไม้แบบง่าย

แต่ฉันไม่เห็นข้อได้เปรียบที่แท้จริงของเขตสีแดง หน่วยความจำเข้าถึงเกินตัวชี้สแต็คเป็นสิ่งที่อันตรายมากและสามารถนำไปสู่ความเสียหายของข้อมูล ทำไมถึงทำเช่นนี้? การบันทึกคำสั่งของโปรเซสเซอร์ 2 ตัว (push ebp; mov ebp esp) จะไม่ทำให้ความเร็วเพิ่มขึ้นจริง

คำตอบ:


16

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

sub XXX, %rsp 

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

หากคุณไม่ต้องย่อยจากตัวชี้สแต็คอีกครั้งรหัสที่ปล่อยออกมาสามารถใช้ rsp เป็นตัวชี้พื้นฐานงานที่สงวนไว้สำหรับ rbp ตามปกติและรหัสที่ปล่อยออกมาสามารถใช้ rbp เป็นทะเบียนทั่วไปอื่นได้

ท้ายที่สุดนี้หมายถึงคำนำหน้าและบทส่งท้ายของการเรียกใช้ฟังก์ชันแต่ละครั้งสามารถบันทึกสองคำสั่งที่จะบันทึกและกู้คืน rbp:

(แอสเซมเบลอร์ gnu)

pushq %rbp       # prologue [ two instructions not necessary ]
movq %rsp,%rbp

.... [code]

movq %rbp,%rsp   # epilogue [ two instructions not necessary ]
popq %rbp        

โปรดทราบว่าใน gcc คุณสามารถส่งผ่านแฟล็ก -mno-red-zone หากคุณไม่ต้องการ (แต่ x86-64 ABI ต้องการมัน) เคอร์เนล Linux ไม่จำเป็นต้องสอดคล้องกับ ABI และทำให้โค้ดเคอร์เนลทั้งหมดถูกคอมไพล์ด้วย -mno-red-zone

นอกจากนี้การเข้าถึงหน่วยความจำเกินกว่าตัวชี้สแต็กจะไม่เป็นอันตรายหากเป็นโหมดการทำงานที่คาดหวัง มันอันตรายเท่านั้นและอาจนำไปสู่การทุจริตเมื่อไม่ได้วางแผนและไม่คาดคิด เมื่อรหัสที่ปล่อยออกมาทำมันจะรู้ว่ามันกำลังทำอะไรอยู่


ใช่ฉันเข้าใจสิ่งนี้ แต่การบันทึก 1 คำสั่ง (sub จาก esp) เป็นการเพิ่มประสิทธิภาพจริงหรือ ฉันหมายถึงการประหยัดไม่กี่ไบต์และ 1 รอบการประมวลผลสำหรับราคาที่เป็นไปได้จริงของข้อมูลที่เสียหายดูแปลก ๆ อาจจะมีเหตุผลอื่น ๆ
Alexander Dzyoba

3
มันไม่ใช่ sub จาก esp ที่เป็น optimization แต่เนื่องจากคุณไม่ต้อง sub จาก esp อีกต่อไปคุณสามารถใช้ esp เป็นตัวชี้พื้นฐาน (โดยปกติทำโดย ebp) และใช้ ebp สำหรับสิ่งอื่นในโค้ดฟังก์ชัน ในที่สุดเพราะ esp ตอนนี้เป็นตัวชี้ฐานรหัสจึงสามารถหลีกเลี่ยงการบันทึกและเรียกคืน ebp ในอารัมภบท / บทส่งท้าย ฉันจะชี้แจงคำตอบด้วยข้อมูลพิเศษนี้
Brian Onn

แก้ไขและเปลี่ยนเป็น rbp / rsp แทน ebp / esp เนื่องจากโซนสีแดงเป็นเพียงส่วนหนึ่งของ x86-64 ABI (แม้ว่าจะไม่มีสิ่งใดที่ป้องกันไม่ให้ใครใช้เทคนิคเดียวกันกับการลงทะเบียนแบบ 32 บิต แต่ไม่มีคอมไพเลอร์ทำอย่างนั้นในวันนี้)
Brian Onn

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