Как стать автором
Обновить

[The Old New Thing] Могу ли я использовать свой стек как угодно?

Время на прочтение 3 мин
Количество просмотров 4.6K
Всего голосов 17: ↑16 и ↓1 +15
Комментарии 24

Комментарии 24

В Windows стек растет от больших адресов к меньшим

Причем здесь Windows? Это определяется архитектурой процессора.
Иногда это определяется архитектурно, а иногда это просто принятое соглашение

Какое соглашение??? Есть процессоры без команды ret? Там что, вместо ret так: mov rip, [rsp]? бред какой-то…
Да, у нас есть соглашение о кодировании для ассемблера.

Какие соглашения? У кого «у нас»?
У платформы Itanium стоит отметить особенность: там красная зона расположена над указателем стека, а не под ним.

Почему? Там стек расположен по другому? Или как?
Почему у ARM32 8 байт под указателем не меняется? А если прерывание, тогда как?
Почему у ARM64 16 байт под указателем не может быть изменено?
В случае PowerPC красная зона является побочным эффектом соглашения о вызовах.

По ссылке — соглашение о вызовах виндовс на power pc.
Если честно, я вообще не понял о чем статья. Одно название чего стоит…
Кто-то понимает, о чем тут речь? )))
Направление роста стека не всегда определяется архитектурой процессора. У PDP-11, например, стек мог расти в любую сторону, а push и pop были макросами. Что касается вызова подпрограмм, у ARM нет инструкций call и ret, есть только регистр связи − условная верхушка стека вызовов.

Основной посыл статьи понятен и даже банален: не используй для хранения данных незаполненную часть стека, потому что она может быть перезаписана в любой момент (в результате обработки прерывания, например). Но вот про «красную зону» я не знал. Хотя, как я понимаю, использование «красной зоны» на практике − довольно грязный хак, даже когда это безопасно.
У PDP-11, например, стек мог расти в любую сторону, а push и pop были макросами.
Зачем поднимать почившую в бозе экзотику? Современный ARM (но не ARM64 AKA AArch64) устроен так же: выделенного регистра стека нет, стек может расти в любую сторону, а если захотеть — можно завести 2, 3, 8 равноправных стеков.

Хотя, как я понимаю, использование «красной зоны» на практике − довольно грязный хак, даже когда это безопасно.
На Linux активно используется — там она 128 байт на x86-64.
Зачем поднимать почившую в бозе экзотику?

Ну, режимы адресации у VAX'а, наследника PDP, скажем прямо, очень разнообразны.
Вы хотите сказать, что VAX живее PDP??? Когда последняя версия вышла?
Я хочу сказать, что VAX — интересный пример гибкой архитектуры команд, когда бы он ни был в работе. Не вижу смысла в сугубо теоритическом вопросе/споре ограничиваться только популярными ныне технологиями.
Не вижу смысла в сугубо теоритическом вопросе/споре ограничиваться только популярными ныне технологиями.
А я — вижу. Например можно очень долго обсуждать вопросы переносимости на процессоры, где отрицательные числа храняться в обратном коде, а можно — как, наконец-то, поступил комитет по стандартизации к выходу C++20, объявить что «баста карапузики — теперь только дополнильный код». Можно рассказывать байки про то, что на PDP-10 байт был от одного до 36 бит и память на «современные» байты не билась (потому во всех сетевых стандартах в 70е использовался термин «октет», чтобы не было путаницы) — а можно смириться с тем, что всё — это интересно только историкам…

Терминология со временем меняется — потому наличие современного процессора — для обсуждения всяких тонкостей необходимо… если вы не цифровой археолог, конечно.
Терминология со временем меняется — потому наличие современного процессора — для обсуждения всяких тонкостей необходимо… если вы не цифровой археолог, конечно.

Это пустой формализм. Кто-то воспринимает отсутствие уточнения про «современный» процессор как открытую карту для обсуждения любых архитектур. кто-то считает это слово подразумевающимся.

Допустим, у нас не было бы современной архитектуры с какой-то отличительной особенностью — почему не вспомнить про исторические примеры?
Допустим, у нас не было бы современной архитектуры с какой-то отличительной особенностью — почему не вспомнить про исторические примеры?
Потому что вы потеряете способность общаться с людьми. Если вы напишите очень умное рассуждение, в котором будете использовать байты нечётной длины (а на PDP-10 были популярны 9-битные, например), а потом на него сошлётесь в статье про PHP — то вы ничего, кроме раздражения, у читателя не вызовите.

Ну не работает PHP на таких архитектурах — и никогда работать не будет!
Потому что вы потеряете способность общаться с людьми.

Нет, потому что мы обсуждаем общетеоритический вопрос. Пример с PHP, имеющим практические ограничения, здесь неуместен.
Я напомню изначальный тезис:
Какое соглашение??? Есть процессоры без команды ret? Там что, вместо ret так: mov rip, [rsp]? бред какой-то…


В общем и целом, это бесполезный разговор с хождением по кругу. За сим прерываю его.
Точно! Почитал архитектуру ARM, действительно определяется соглашением. Правда, один вариант считается стандартом. Про регистр связи мне понравилось — его содержимое можно сохранить один раз на входе в пп и восстановить при выходе. И потом вызывать другие пп без обращений к памяти, неплохо. А для простых пп, если вложенных вызовов нет, просто не трогаем этот регистр.
Кстати, а на каких платформах Windows работает? x86, PowerPC… про ARM что-то слышал — есть уже или в процессе только? Вообще, хотелось бы ее на ARM, очень уж экономичные они :)
Понятно. Жалуются на производительность
Сыровата технология еще. Похоже, эмуляция используется частенько.
В случае PowerPC красная зона является побочным эффектом соглашения о вызовах.
По ссылке — соглашение о вызовах виндовс на power pc.
Если честно, я вообще не понял о чем статья. Одно название чего стоит…
Кто-то понимает, о чем тут речь? )))
Я, в свою очередь, не понимаю чего вы не понимаете. Соглашение о вызовах на PowerPC (описанное по ссылке) устроено так, что вначале ниже SP кладутся параметры (232 байта), а потом SP сдвигается так, что он оказывается «под ними». Соотвественно все штуки которые могу асинхронно использовать стек должны эту зону не трогать — а вдруг вы параметры уже сложили, а вызов ещё не успели сделать? Де-факто получается «красная зона», хотя они таковой и не была задумана…
Причем здесь Windows? Это определяется архитектурой процессора.

Windows тут как конкретная реализация.


Какие соглашения?

Coding conventions


У кого «у нас»?

У одной из команд Microsoft, в частности, в которой работает Raymond Chen.


Почему? Там стек расположен по другому? Или как?

Думаю это выходит за рамки статьи. Вероятнее всего больше информации содержится в приведенной автором (и повторенной мной) ссылке.


Почему у ARM32 8 байт под указателем не меняется? А если прерывание, тогда как?

Не уверен за ARM, но прерывания, вроде не должны исполняться на стеке пользовательского пространства.


Почему у ARM64 16 байт под указателем не может быть изменено?

Потому, что это красная зона, которую ОС не трогает.


По ссылке — соглашение о вызовах виндовс на power pc.

А что должно быть по ссылке, озаглавленной "побочный эффект соглашения о вызовах"?


Если честно, я вообще не понял о чем статья. Одно название чего стоит…
Кто-то понимает, о чем тут речь? )))

В статье рассматривается вопрос о возможности в Windows хранения данных с стеке по отрицательным смещениям относительно указателя стека (за красной зоной).

Дурной пример. Почему? Потому что для linux или freebsd можно показать что именно там делает ядро со стеком (сырцы доступны), а у винды бага на гитхабе и сырцы всё ещё не доступны.
Автору переведённой статьи сырцы более, чем доступны: их часть он сам и писал.
Что начинает звучать как издевательство над читателем. У меня есть, но не покажу.
Интересно, а почему под некоторые архитектуры red zone имеет размер 0? :) Штука-то удобная, можно было бы юзать для разных отладочных целей. Есть какие-то другие механизмы, замещающие red zone или так сделали «потому что»? Насколько я помню, в Linux для x86_64 red zone имеет размер аж 128 байт, так что вряд ли это аппаратные ограничения.

Как минимум, использование "в отладочных целях" (помнится, на 8080 это было вообще неизбежно, брейкпойнты ставились внедрением в код команды типа RST 3 — по сути, call 18h, кладёт в стек) исключает использование для чего-то ещё.
А на 8086/88 под DOS порчу памяти под стеком использовали защиты софта для обнаружения отладчика.

Конечно, не аппаратные, просто соглашение. Даже не знал о существовании подобного, всегда считал, что все что меньше SP, может меняться в любой момент.
Соглашение о вызовах на PowerPC (описанное по ссылке) устроено так, что вначале ниже SP кладутся параметры (232 байта), а потом SP сдвигается так, что он оказывается «под ними»

Но можно же вначале сдвинуть SP, а потом положить? В чем смысл таких манипуляций? Поддержка этой red zone требует ресурсов — необходимо помнить о ее наличии, что бы случайно не поменять. Зачем?
Эффективность. RISC. Все инструкции имеют одинаковую длину (обычно 4 байта), что значит, что оффсеты в инструкциях, манипулирующих со стеком ограничены (обычно что-то типа ±4K допускается). Если мы разрешим использовать только область памяти «выше» SP, то максимальный объём «фрейма», с которым мы можем работать быстро — уменьшается. А главное — размер начинает зависеть от того, какие функции мы будем вызывать и сколько у них параметров…
А вот это уже аргумент…
Зарегистрируйтесь на Хабре , чтобы оставить комментарий

Публикации

Истории