тролль - это не только ценный жир, но и 3-4 легкоусвояемых коммента ежедневно
Господа, поясните пожалуйста, зачем нужна эта красная зона в стеке?
Что этим пытаются выиграть? И выигрывают ли что-нибудь?
Чем это лучше, чем старый добрый способ (sub ESP,nnnn в вызванной функции)?

@темы: Assembler, Вопрос, ABI

Комментарии
13.05.2015 в 22:04

IDDQD - Команда молодости нашей, команда, без которой мне не жить.
Подозреваю, что это будет эффективно работать только в том случае, если сдвиг SP будет происходит в момент выполнения CALL. В принципе, 128 байт вполне достаточно для хранения локальных переменных. Если нужно больше - будет ручной сдвиг.
14.05.2015 в 05:32

тролль - это не только ценный жир, но и 3-4 легкоусвояемых коммента ежедневно
Проверил Вашу гипотезу - поискал архитектуры, на которых работала System-V, и в которых была бы такая инструкция вызова подпрограмм, которая бы резервировала эти 128 байт в стеке. Не нашёл.

Зато благодаря этим поискам открыл для себя архитектуру PowerPC. Я до сих пор жил счастливо и не знал, что такое безобразие существует в природе!
В толстенном описании этой процессорной архитектуры слово "стек" не встречается вообще! Инструкции вызова подпрограмм и не подозревают о существовании стека! При вызове подпрограммы адрес возврата заносится в спец. регистр, а сохранять его из этого спец.регистра куда-нибудь в память - забота программиста. Нету команд PUSH/POP. Автоинкремент/автодекремент указателя при сохранении данных в память не поддерживается аппаратно. Такое впечатление, что стек - это чисто софтовая заморочка, которой может и не быть. Будет у программиста 0 стеков, 1 стек или 30 стеков одновременно - процессору всё равно: хочешь стек - бери любой регистр (их там 32) и используй его как указатель стека ))) Но удобных PUSH/POP всё равно не будет.
Наверное, именно с этой архитектуры и пошло это странное требование: делать кадры стека большими и создавать в них место про запас, чтобы вызываемые функции не строили свой кадр стека, а использовали зарезервированное для них место в кадре стека вызвавшей их функции.
Вот тут (стр 17) написана интересная деталь про создание кадра стека: нужно атомарной(!) операцией записать в начало нового кадра стека адрес предыдущего кадра и одновременно записать в указатель стека адрес нового кадра. Для сравнения: x86 такого атомарно делать не умеет!
А вот тут написано, как люди мучаются, перенося идеологию "красной зоны" на x86.
17.05.2015 в 01:09

CD_Eater, Это понятие в основном нужно для работы сигналов. Сигналы ведь прилетают внезапно, как прерывания, при этом им нужен кусок стека под их локальные переменные. Вот и договорились, что стек ниже красной зоны можно невозбранно портить, а выше - нельзя. Поэтому при вызове сингала esp смещается на размер красной зоны вниз и вызывается обработчик сигнала.
17.05.2015 в 07:56

тролль - это не только ценный жир, но и 3-4 легкоусвояемых коммента ежедневно
einsammann, требование этой красной зоны означает гарантию сохранности данных НИЖЕ ESP!!! на каких архитектурах такое вообще возможно?
на большинстве процессорных архитектур понятие "вызов обработчика (сигнала,прерывания,...)" означает неизбежное затирание нескольких байт ниже ESP прерываемого процесса

Поэтому при вызове сингала esp смещается на размер красной зоны вниз и вызывается обработчик сигнала.
как происходит это смещение ESP вниз? аппаратно или программно?
17.05.2015 в 11:36

CD_Eater,
требование этой красной зоны означает гарантию сохранности данных НИЖЕ ESP!!! на каких архитектурах такое вообще возможно?
А в чём проблема? Это сделано специально для того, чтобы функция могла не делать sub esp, xxx, если размер её фрейма небольшой и она не вызывает других функций. Она в этом случае будет работать со адресами, которые меньше значения esp.

как происходит это смещение ESP вниз? аппаратно или программно?
Программно. Аппаратная часть не умеет соблюдать красную зону.

Ах да, если не ошибаюсь, прерывание обычно приводит к записи данных в стек ядра, а не в стек пользователя.
17.05.2015 в 11:53

тролль - это не только ценный жир, но и 3-4 легкоусвояемых коммента ежедневно
einsammann, Ах да, если не ошибаюсь, прерывание обычно приводит к записи данных в стек ядра, а не в стек пользователя.
Если прерывание выполняется в своём стеке, то ему абсолютно фиолетово на какую-то там красную зону в стеке пользователя.
А если прерывание выполняется на стеке прерываемой программы - то я не понимаю, как она может соблюсти эту красную зону. Прежде чем обработчик прерывания получит управление, в стек уже что-то понапихается )))
17.05.2015 в 12:06

CD_Eater, я поэтому и написал, что красная зона нужна для работы сигналов. Там всё программно учитывается.
17.05.2015 в 12:38

тролль - это не только ценный жир, но и 3-4 легкоусвояемых коммента ежедневно
einsammann, я не понял вашу мысль. поясните подробнее.
17.05.2015 в 12:48

CD_Eater, красная зона создана для защиты пользовательских данных от повреждения во время вызова прерываний и сигналов. Но в x86 прерывания никак не могут учитывать это, поэтому прерывания обычно обрабатывают в ядре, где данные пишутся на ядерный стек, на не на пользовательский. Таким образом пользовательский стек не портится. Сигналы же обрабатываются в пространстве пользователя в рамках имеющейся задачи, с использованием стека этой задачи. Поэтому здесь для сохранения пользовательских данных указатель стека сдвигается вниз на размер красной зоны (на самом деле она начинается ещё выше, но так получается "с гарантией") перед вызовом функции обработки сигнала и размещением параметров на стеке.
17.05.2015 в 13:23

тролль - это не только ценный жир, но и 3-4 легкоусвояемых коммента ежедневно
einsammann, спасибо, дошло ))