Вероятно, лучше всего, чтобы ваша функция 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 до адреса возврата в стеке и расположения любых сохраняемых вызовов регистров. Таким образом, вы можете восстановить их и продолжить раскручивать в родительский, используя этот обратный адрес.