Как увидеть результат директив MASM, таких как PRO C, .SETFRAME. .PUSHREG - PullRequest
0 голосов
/ 27 марта 2020

Написание ассемблерного кода x64 с использованием MASM, мы можем использовать эти директивы для предоставления информации о разворачивании фрейма. Например, из .SETFRAME определение:

Эти директивы не генерируют код; они генерируют только .xdata и .pdata.

Поскольку эти директивы не производят никакого кода, я не вижу их эффектов в окне разборки. Итак, я не вижу никакой разницы, когда я пишу функцию сборки с этими директивами или без них. Как я могу увидеть результат этих директив - используя dumpbin или что-то еще?

Как написать код, который может проверить эту возможность раскручивания? Например, я специально пишу ассемблерный код, который вызывает исключение. Я хочу видеть разницу в поведении обработки исключений, когда функция написана с этими директивами или без них.

В моем случае вызывающая программа написана на C ++ и может использовать try-catch, SSE et c. - все, что имеет отношение к этой ситуации.

1 Ответ

2 голосов
/ 27 марта 2020

Вероятно, лучше всего, чтобы ваша функция asm вызывала другую функцию C ++, а ваша функция C ++ вызывала исключение C ++. (Не похоже на недопустимую память из asm, которая приведет к сбою и может привести к обработчику SEH. Обычные исключения C ++ проще, чем Windows SEH).

Так что создайте ситуацию, когда исключение C ++ должно разматывать стек через ваша асм функция; если это работает, то вы получили правильные директивы метаданных по стеку. В частности, try{}catch в вызывающем C ++ и throw в функции C ++ вы call из asm.

Этот метатель, я могу назвать extern "C", так что вы можете вызвать его из asm без искажения имени , Или вызовите его через указатель на функцию, или просто посмотрите на вывод компилятора MSV C и скопируйте искаженное имя в asm.


Кстати, не-1024 * (например, GNU / Linux ) эквивалентом этих метаданных являются директивы DWARF .cfi, которые создают раздел .eh_frame.

Я не знаю эквивалентных деталей для Windows, но я знаю, что они используют аналогичные метаданные, которые позволяют разматывать стек, не полагаясь на указатели кадров RBP. Это позволяет компиляторам создавать оптимизированный код, который не тратит впустую инструкции на push rbp / mov rbp,rsp и leave в прологах / эпилогах функций, и освобождает RBP для использования в качестве регистра общего назначения. (Еще более полезно в 32-битном коде, где 7 вместо 6 регистров, кроме указателя стека, гораздо сложнее, чем 15 против 14.)

Идея состоит в том, что при наличии RIP вы можете посмотреть смещение от RSP до адреса возврата в стеке и расположения любых сохраняемых вызовов регистров. Таким образом, вы можете восстановить их и продолжить раскручивать в родительский, используя этот обратный адрес.

...