如何查看MASM指令(例如PROC,.SETFRAME)的结果。 .PUSHREG

问题描述 投票:0回答:1

使用MASM编写x64汇编代码,我们可以使用这些指令来提供退帧信息。例如,从.SETFRAME定义中:

这些指令不会生成代码;它们仅生成.xdata和.pdata。

由于这些指令不会产生任何代码,因此我无法在反汇编窗口中看到其效果。因此,当我编写带有或不带有这些指令的汇编函数时,我看不出任何区别。

我如何查看这些指令的结果-使用.SETFRAME或其他?


如何编写可以测试此展开功能的代码?例如,我故意编写导致异常的汇编代码。我想看看使用或不使用这些指令编写函数时异常处理行为的差异。

就我而言,呼叫者是用C ++编写的,可以使用dumpbin,SSE等-与这种情况有关的任何东西。

windows visual-studio assembly x86-64 masm
1个回答
0
投票

[最好的选择是让asm函数调用另一个C ++函数,并使C ++函数抛出C ++异常。 (不像来自asm的非法内存那样,它会发生故障并可能导致SEH处理程序。正常的C ++异常比Windows SEH更简单)。

因此,需要创建一个C ++异常需要通过asm函数展开堆栈的情况;如果可行,那么您可以正确执行堆栈展开元数据指令。具体来说,C ++调用程序中的try-catch和C ++函数中的try{}catch是您从asm throw获得的。

我认为那个投掷者是call,因此您可以从asm调用它,而无需更改名称。或通过函数指针调用它,或仅查看MSVC编译器的输出并将错误的名称复制到asm。


BTW,此元数据的非Windows(例如GNU / Linux)等效项是DWARF extern "C"指令,该指令创建了.cfi节。

我不知道Windows的等效详细信息,但我确实知道它们使用类似的元数据,这使得无需依赖RBP帧指针即可展开堆栈。这使编译器可以编写优化的代码,而不会浪费函数序言/结尾中的.eh_frame / push rbpmov rbp,rsp上的指令,并释放了RBP用作通用寄存器。 (在32位代码中更有用,在该代码中,除了堆栈指针外,还有7个寄存器而不是6个寄存器比15 vs. 14要大得多。)

这个想法是,给定一个RIP,您可以查找从RSP到堆栈上返回地址的偏移量,以及任何保留呼叫的寄存器的位置。因此,您可以还原它们,并使用该返回地址继续展开到父级。

最新问题
© www.soinside.com 2019 - 2024. All rights reserved.