Я пишу сборку x64 для ассемблера GNU. Я пытался читать о директивах .seh_*, но не нашел о них много информации. В документах gas
они вообще не упоминаются.
Но насколько я понимаю, если мой код может оказаться в стеке во время операции раскрутки SEH, я должен использовать их. И поскольку мой код выполняет манипуляции со стеком и вызывает другие функции, SEH возможен, поэтому я должен использовать их.
В основном я думаю, что я понял это правильно:
.seh_proc FCT
FCT:
push %rbp
.seh_pushreg %rbp
mov %rsp, %rbp
.seh_setframe %rbp, 0
push %r14
.seh_pushreg %r14
lea -(iOffset + iBytes)(%rsp), %rsp
.seh_stackalloc iOffset + iBytes
andq $-16, %rsp <---- But what about this?
.seh_endprologue
etc...
Но есть один момент, который не ясен. У меня есть такая инструкция:
andq $-16, %rsp
Как мне сообщить SEH, что я выполняю выравнивание стека? Это может скорректировать стек от 15 байтов (очень маловероятно) до 8 байтов (очень вероятно) и до 0 байтов (конечно возможно). Поскольку реальная сумма не может быть определена до времени выполнения, я застрял.
Я полагаю, что могу пропустить инструкцию .seh, но если там зарезервировано 8 байтов стека, я, вероятно, испортил раскрутку, не так ли? Разве это не противоречит всей цели?
В качестве альтернативы я могу опустить выравнивание. Но если я вызову другие функции (скажем, memcpy), разве я не должен выравнивать стек? Согласно MS:
Стек всегда будет выровнен по 16 байтам, за исключением пролога.
Может быть, я могу «рассуждать» об этом? Если парень, который мне позвонил, сделал все правильно (если...), то стек был выровнен, когда он сделал call
, так что теперь я отстаю на 8 байт (обратный адрес) плюс все, что я делаю в своем прологе. Могу ли я зависеть от этого? Кажется хрупким.
Я пытался смотреть на другой код, но я не уверен, что доверяю тому, что вижу. Я сомневаюсь, что gas
сообщает об ошибках из-за неправильного использования .seh_*. Вы, вероятно, увидите проблему только во время фактического исключения (и, возможно, не всегда даже тогда).
Если я собираюсь сделать это, я хотел бы сделать это правильно. Кажется, что выравнивание стека будет обычным делом, поэтому у кого-то должно быть решение. Я просто не вижу этого.