20:19 

Извращения со стеком

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

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

Комментарии
2015-05-13 в 22:04 

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

2015-05-14 в 05:32 

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

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

2015-05-17 в 01:09 

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

2015-05-17 в 07:56 

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

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

2015-05-17 в 11:36 

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

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

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

2015-05-17 в 11:53 

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

2015-05-17 в 12:06 

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

2015-05-17 в 12:38 

CD_Eater
в опе ещё играет детство, а жить уже надо по-взрослому
einsammann, я не понял вашу мысль. поясните подробнее.

2015-05-17 в 12:48 

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

2015-05-17 в 13:23 

CD_Eater
в опе ещё играет детство, а жить уже надо по-взрослому
einsammann, спасибо, дошло ))

Комментирование для вас недоступно.
Для того, чтобы получить возможность комментировать, авторизуйтесь:
 
РегистрацияЗабыли пароль?

ru_programming

главная