Мога ли да използвам 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
Работи в потребителско пространство. Под манипулатори на сигнали имате предвид линукс манипулатори на сигнали?   -  person kvanbere    schedule 06.03.2014
comment
ако използвате rsp като GPR, тогава къде ще съхранявате стойността му? Ако не съхранявате 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 понякога имаше смисъл; ето защо дискусията за това може да се намери в контекста на филтрите за виртуален дублатор.

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

person Peter Cordes    schedule 06.10.2020