Яке призначення червоної зони?


12

Червона зона - це область фіксованого розміру в пам'яті поза вказівкою стека, яка не була "виділена". Компілятори генерують збірку, щоб отримати доступ до цієї області у простих функціях аркуша.

Але я не бачу реальних переваг для червоної зони. Доступ до пам’яті поза вказівником стека є дійсно небезпечним і може легко призвести до пошкодження даних . Навіщо навіть це робити? Збереження 2 інструкцій процесора (push ebp; mov ebp esp) не дасть реальної швидкості.

Відповіді:


16

Червона зона - це чисто і просто оптимізація, яка може зберегти інструкції. Це означає, що більше не потрібно, щоб випромінюваний код для кожної функції віднімався від вказівника стека, щоб зробити місцевий сховище таким

sub XXX, %rsp 

на початку кожного виклику функції, навіть якщо вони не є функціями листів. Часто код, який випускається з компілятора, може використовувати тимчасовий пробіл у червоній зоні під вказівником стека, не потребуючи його збереження та перед викликом інших функцій. Це корисна оптимізація для наявності.

Якщо вам більше не доведеться переводити підказку з покажчика стека, випромінюваний код може використовувати 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, якщо цього не хочете (але ABI x86-64 цього вимагає). Ядро Linux не повинно бути сумісним з ABI, і тому весь код ядра компілюється з -mno-red-zone.

Крім того, доступ до пам'яті поза вказівником стека не є небезпечним, якщо це очікуваний режим роботи. Це лише небезпечно і може призвести до корупції, коли це непередбачувано і несподівано. Коли випущений код робить це, він знає, що робить.


Так, я це розумію. Але чи збереження 1 інструкції (суб від esp) - це справді оптимізація? Я маю на увазі заощадження кількох байтів і 1 процесорний цикл для ціни реальної можливості пошкодження даних виглядає дивно. Може, є якісь інші причини для цього?
Олександр Дзьоба

3
Дійсно, що sub від esp не є оптимізацією, але оскільки вам більше не доведеться переводити на esp, ви можете використовувати esp як базовий покажчик (як правило, виконується ebp) і використовувати ebp для чогось іншого у коді функції. Нарешті, оскільки esp тепер є базовим покажчиком, код може уникнути збереження та відновлення ebp у пролозі / епілозі. Я поясню відповідь цією додатковою інформацією
Брайан Онн

редагуйте та змініть на rbp / rsp замість ebp / esp, оскільки червона зона є лише частиною ABI x86-64 (хоча ніщо не заважає використовувати ту саму техніку з 32-бітовими регістрами; але жоден компілятор не робить це так сьогодні)
Брайан Онн

1
Опущення покажчика кадру взагалі не пов'язане з червоною зоною - компілятор може індексувати стек, використовуючи %rspяк базовий вказівник будь-яким способом.
alecov
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.