Могу ли я использовать rsp в качестве регистра общего назначения?

Мне сказали, что если я использую rsp в качестве регистра общего назначения, операционная система может сбрасывать регистры туда, куда он указывает в случае прерывания, вызывая проблемное поведение.

Верно ли это, и если нет, то, если мне не нужен стек, могу ли я использовать rsp в качестве регистра общего назначения?

Изменить: работает в пользовательском пространстве.


person kvanbere    schedule 05.03.2014    source источник
comment
Я верю, что это правда. Кроме того, где бы вы сохранили реальное значение rsp, которое вам нужно восстановить перед вызовом или возвратом в O/S?   -  person 500 - Internal Server Error    schedule 06.03.2014
comment
Другой регистр. Я хотел бы иметь возможность использовать push/pop/ret для взаимодействия с буфером в течение длительного периода времени.   -  person kvanbere    schedule 06.03.2014
comment
Я использовал указатель стека в качестве указателя данных на z80, но я не понимаю, почему вы не можете и почему вы должны это делать.   -  person Jens Björnhager    schedule 06.03.2014
comment
Например, ret 04 имеет некоторые лучшие характеристики производительности (например, предсказание переходов), чем jmp dword ptr [eax+4].   -  person kvanbere    schedule 06.03.2014
comment
Зачем вам нужен rsp как универсальный? В некоторых случаях это возможно, но я не думаю, что наличие еще одного регистра значительно повысит производительность и может привести к проблемам.   -  person phuclv    schedule 06.03.2014
comment
Это действительно крайний случай, когда повышение производительности может быть достаточно значительным, чтобы сделать это, но попытка объяснить это здесь не входит в рамки вопроса :)   -  person kvanbere    schedule 06.03.2014
comment
Вам нужно уточнить контекст, в котором вы работаете. Это пространство пользователя? Это в привилегированном режиме или в режиме ядра? Даже в пользовательском пространстве обработчики сигналов могут быть проблемой, поскольку они используют пространство стека в красной зоне x86-64, требуя действительного rsp.   -  person Brett Hale    schedule 06.03.2014
comment
Запуск в пользовательском пространстве. Под обработчиками сигналов вы имеете в виду обработчики сигналов Linux?   -  person kvanbere    schedule 06.03.2014
comment
если вы используете rsp в качестве георадара, то где вы будете хранить его значение? Если вы нигде не храните rsp, то как вы можете восстановить его при возврате к вызывающей функции?   -  person phuclv    schedule 06.03.2014
comment
Если вам нужен еще 1 регистр, вы пробовали -fomit-frame-pointer?   -  person phuclv    schedule 06.03.2014
comment
@BrettHale: Сигналы можно разделить на 2 категории: те, которые никогда не должны были существовать (поскольку они указывают на то, что программа содержит ошибки и что им не следует доверять обработку ее сбоев), и те, которые никогда не должны были существовать (поскольку лучше использовать подход с опросом, такой как get_next_queued_event(), особенно когда задействовано несколько потоков, и сигнал может прерываться, пока потоки удерживают любое количество блокировок/мьютексов). ;-)   -  person Brendan    schedule 06.10.2020
comment
@phuclv: хранить RSP в глобальном масштабе в однопоточной программе или в переменной локального хранилища потока в потокобезопасном коде. (Или в любом из XMM0..15 или mm0..7; x86-64 гарантирует SSE2... Но обычно вы должны просто использовать эти векторные регистры вместе с 15 целочисленными регистрами и оставить RSP в покое.)   -  person Peter Cordes    schedule 06.10.2020
comment
Отвечает ли это на ваш вопрос? Является ли ESP таким же универсальным, как EAX?   -  person phuclv    schedule 07.10.2020


Ответы (2)


Разве вы не облажались, если произойдет прерывание?

Те из вас, кто программировал в DOS, скорее всего, сейчас сомневаются в возможности прерываний. Обычно такое повторное использование указателя стека — очень плохая идея, потому что вы понятия не имеете, когда может сработать прерывание, и когда это происходит, ЦП покорно помещает текущий счетчик программ и флаги в стек. Если вы повторно использовали ESP, это привело бы к уничтожению случайных структур данных. В такой среде ESP всегда должен указывать на действительное и достаточное пространство стека для обслуживания прерывания, а когда это не так, прерывания должны быть отключены. Работа с отключенными прерываниями в течение длительного времени снижает скорость отклика системы (потерянные прерывания и большая задержка) и непрактична для большой рутины.

Однако здесь мы работаем в защищенном режиме.

При работе в пользовательском пространстве в Win32 прерывания помещаются не в пользовательский стек, а вместо этого в стек ядра. Если подумать, использование пользовательского стека невозможно. Если бы потоку не хватило места в стеке или даже просто имелся недопустимый стек, когда ЦП пытался отправить EIP и EFLAGS, возник бы сбой страницы, а вы не можете сбой страницы в обработчике прерывания. Таким образом, планировщик может выполнять любое количество переключений контекста во время выполнения подпрограммы без стека, и любые структуры данных, которые указываются как ESP, не будут затронуты.

Из http://www.virtualdub.org/blog/pivot/entry.php?id=85

person kvanbere    schedule 06.03.2014
comment
Это правда, но также помните, что обработчик сигнала использует пользовательский стек (как упоминал Бретт Хейл в вопросе). Два варианта, о которых нужно позаботиться: заблокировать все сигналы или настроить собственный стек для любых незаблокированных сигналов. - person ughoavgfhw; 06.03.2014
comment
Как я могу настроить собственный стек для разблокированных сигналов? - person kvanbere; 06.03.2014
comment
Используйте sigaltstack для настройки стека, затем при установке обработчиков используйте sigaction и укажите SA_ONSTACK во флагах. - person ughoavgfhw; 06.03.2014

Да, вы могли бы при очень контролируемых обстоятельствах, но на практике вместо этого просто используйте SSE2 и/или MMX.


Связанный: Действительно ли писать ниже ESP? обсуждает вещи в Windows который может асинхронно использовать указатель стека в 32-битном коде. С недопустимым указателем стека эти вещи будут падать, а не наступать на пространство под ним. (Или, если вы указываете на доступную для записи память, используйте ее как пространство стека.)

В GNU/Linux обработчики сигналов могут асинхронно использовать указатель стека пользовательского пространства, но вы можете использовать sigaltstack/SA_ONSTACK, чтобы использовать для них альтернативный стек.


Также обратите внимание, что x86-64 гарантирует SSE2. Обычно вам нужно рассмотреть возможность использования RSP в качестве 16-го регистра общего назначения только в том случае, если вы уже использовали все xmm0..15 (SSE) и mm0..7 (MMX).

Использование ESP в качестве 8-го регистра общего назначения в 32-битном коде DSP для процессоров без MMX иногда имело смысл; вот почему обсуждение этого можно найти в контексте фильтров virtualdub.

Как правило, это не имеет смысла в 64-битном коде, потому что у вас всегда есть 16x 128-битных SIMD-регистров (и SIMD-инструкции для их использования), а также более чем в два раза больше нестековых регистров. Целочисленные регистры указателей. И 8x 64-битных регистров mmx или 8x 80-битных регистров x87, как бы ты ни хотел их использовать. В большинстве соглашений о вызовах большинство этих регистров затираются вызовами, но вы все равно не могли бы выполнять вызовы функций с RSP, не указывающим на стек.

person Peter Cordes    schedule 06.10.2020