64位Windows ABI定义了一个通用的exception handling mechanism,我认为它可以在C ++异常和结构化异常之间共享,即使在其他语言中也是如此。
如果我正在编写一个x86-64程序集例程,要在nasm
中编译并链接到C或C ++库,那么在生成展开信息等方面我需要在Windows上做些什么?
我不打算直接在汇编代码中生成任何异常,但我认为如果用户提供的缓冲区无效等,代码可能会出现访问冲突。
我希望编写尽可能少的代码才能使其工作,特别是因为似乎nasm
对生成展开信息的支持不足,并且使用MASM
不是此选项的选项平台项目。我确实需要使用(因此保存和恢复)非易失性寄存器。
答案 0 :(得分:8)
作为一般规则,Windows x64需要所有功能来提供展开信息。唯一的例外是叶函数不修改v-for
并且不修改任何非易失性寄存器。
答案 1 :(得分:3)
根据您的问题的上下文来判断,您真正想知道的是不在x64 Windows上为非叶装配功能提供展开信息的实际后果。由于C ++异常是基于SEH异常实现的,当我谈到下面的异常时,我的意思是所有“本机”(访问冲突,使用RaiseException
抛出的东西等)和C ++异常。这是我头顶的清单:
重要的是要注意,这一点不是要在您的函数中抛出异常,或直接发生访问冲突。假设您的汇编代码调用C ++函数,该函数抛出异常。即使汇编函数的调用者具有匹配的catch
块,它也永远无法捕获异常,因为展开将在没有展开数据的情况下停止在您的函数中。
基本上,如果你的函数出现在调用堆栈上(调试器显示调用堆栈,分析器等)时,任何走过堆栈的东西都会被搞砸。
Unhandled Exception Filters
这会干扰依赖UEF的任何事情。例如,自定义崩溃处理程序。或者可能更相关的东西:在这种情况下,如果你的程序抛出一个未处理的C ++异常(因为它是由C ++标准规定的),则不会回调std::terminate
。 MSVC运行时使用UEF来实现它,因此这也不会起作用。
您正在开发第三方图书馆吗?如果是这种情况,上述要点的重要性将取决于客户的使用情况。