Вызов функций в Windows на x86-64 низкий уровень; структура стэка — один-четыре вопроса

01.01.2001

Вызов функций в Windows на x86-64 низкий уровень; структура стэка — один-четыре вопроса
Интересует ответ от тех, кто толково разбирается в межмодульных взаимодействиях в Windows+x86-64.
Я сам бывалый в этом плане, но до этого делал всё под 32 бита. А оф. документация (http://msdn.microsoft.com/en-US/library/ew5tede7(v=vs.80).aspx) по x86-64 на сайте MS оставляет не одну многозначность в моём мозгу.

Вопрос 1: Я понял что стэк должен быть выравнен между прологом и эпилогом на 16-байтную границу. При вызове он теряет выравнивание, так как в стэк кладётся 8-байтный адрес возврата и далее нужно нечётное количество 8-байтных чанков прибавить (ну или иначе выровнять) . А где выравнивание располагается? Судя по оф. схеме мне в начале нужно запушить все волайтайлные регистры (RSI, RDI, R12 и т. д.) , а потом уже вставить алигнер (на оф. схеме помечено как malloc). Так ли это?

Вопрос 2: Чем обусловлено выравнивание стэка на 16-байтовую границу? Для 256-битных параметров для SSE или откуда такой дроч? Если есть ссылка на оф. материалы, то +8 часов продуктивной радости вам в карму.

Вопрос 3: На оф. сайте в самом начале есть предложения «The parameter area is always at the bottom of the stack (even if alloca is used), so that it will always be adjacent to the return address during any function call. It contains at least four entries, but always enough space to hold all the parameters needed by any function that may be called». Я понимаю это как: «Нужно как минимум 4 слота под параметры даже если их меньше (выделите больше если их больше четырёх). » Я гляжу примеры в оф. дистрибе FASM и вижу что там не удосуживаются выделить место под них (только под Home ECX, EDX, R15, R16 и выравнивание) . И не падает же, собака (да, глубина вызова у HelloWorld не большая — повезло им; наверное) . Мож я тупой, так как не курил уже три дня, но сегодня в отладчике увидел что MessageBoxTimeout вовсю юзает Home RCX, брезгует Home RDX и сразу юзает то самое место для презерва тех первых четырёх параметров в стэке. Ну вот, если я вызываю беспараметровую GetLastError, то по-любому 4 слота под первые 64-битные параметра плюс 4 слота под Home RCX, RDX, R8, R9 чтоли? Я нихрена не понимаю зачем презервить 4 слота под первые 4 параметра если в стэке есть специальные Home-места. Действительно под них? Я в отладчике видел что их юзают подфункции не брезгуя. Не понимаю нихрена.

Вопрос 4: И что делает это загадочная процедура/макрос __chkstk? Я скока лет уже лопатил справочник по WinAPI-функциям, но ни разу не видел фукнция для презерва места под стэк. Эта хрень __chkstk нужна когда в стэке нужно место больше одной машинной страницы. Врятли она там вызывает VirtualAlloc, а потом фиксит ESP/RSP. Что же она там делает?

Вас заинтересует