Winapi ; /*设置未处理的异常筛选器*/ SetUnhandledExceptionFilter(myfunc); /*做坏事*/ a=5.0/零; printf(“a=%f\n”,a); 返回0; } 默认情况下,MSC编译浮点指令以始终将SSE单元用于64位

Winapi ; /*设置未处理的异常筛选器*/ SetUnhandledExceptionFilter(myfunc); /*做坏事*/ a=5.0/零; printf(“a=%f\n”,a); 返回0; } 默认情况下,MSC编译浮点指令以始终将SSE单元用于64位,winapi,exception,floating-point,structured-exception,Winapi,Exception,Floating Point,Structured Exception,; /*设置未处理的异常筛选器*/ SetUnhandledExceptionFilter(myfunc); /*做坏事*/ a=5.0/零; printf(“a=%f\n”,a); 返回0; } 默认情况下,MSC编译浮点指令以始终将SSE单元用于64位代码。取决于您运行的CPU,\u control87调用可能不会为SSE单元设置相应的MXCSR标志。有关更多详细信息,请参阅。@i不可检测,谢谢您的回复。实际上,在64位平台上,MXCSR显示在ContextRecord下面:ContextR

; /*设置未处理的异常筛选器*/ SetUnhandledExceptionFilter(myfunc); /*做坏事*/ a=5.0/零; printf(“a=%f\n”,a); 返回0; }
默认情况下,MSC编译浮点指令以始终将SSE单元用于64位代码。取决于您运行的CPU,
\u control87
调用可能不会为SSE单元设置相应的MXCSR标志。有关更多详细信息,请参阅。@i不可检测,谢谢您的回复。实际上,在64位平台上,MXCSR显示在ContextRecord下面:
ContextRecord->FltSave.MXCSR
<代码>上下文记录->FltSave.MxCsr_掩码;最后是
ContextRecord->MxCsr
。我想我读到MXCSR的定义与_control87相同,因此我尝试将上述上下文记录的各种组合分配给我的ctrl1变量,但迄今为止没有成功,我想我看到了现在发生的情况:使用FPU代码,当操作失败时,它会设置异常标志,但浮点异常仅在下一条FPU指令上引发。由于异常过滤器指示控制流返回触发异常的操作码(可能是
FST
,而不是实际的除法),且异常位已清除,因此它将继续执行。对于SSE代码,我认为例外情况是由失败的操作码引起的,在您的案例中,该部分。该指令被反复执行。逐步执行汇编以验证这是否正确。默认情况下,MSC编译浮点指令以始终使用64位代码的SSE单元。取决于您运行的CPU,
\u control87
调用可能不会为SSE单元设置相应的MXCSR标志。有关更多详细信息,请参阅。@i不可检测,谢谢您的回复。实际上,在64位平台上,MXCSR显示在ContextRecord下面:
ContextRecord->FltSave.MXCSR
<代码>上下文记录->FltSave.MxCsr_掩码;最后是
ContextRecord->MxCsr
。我想我读到MXCSR的定义与_control87相同,因此我尝试将上述上下文记录的各种组合分配给我的ctrl1变量,但迄今为止没有成功,我想我看到了现在发生的情况:使用FPU代码,当操作失败时,它会设置异常标志,但浮点异常仅在下一条FPU指令上引发。由于异常过滤器指示控制流返回触发异常的操作码(可能是
FST
,而不是实际的除法),且异常位已清除,因此它将继续执行。对于SSE代码,我认为例外情况是由失败的操作码引起的,在您的案例中,该部分。该指令被反复执行。逐步组装以验证这是否正确。
#include "stdafx.h"
#include <float.h>
#include <Windows.h>

double zero = 0.0;
LONG WINAPI myfunc(EXCEPTION_POINTERS * ExceptionInfo){
    /* clear the exception */
    unsigned int stat = _clear87();

    /* disable fp exceptions*/
    unsigned int ctrl1 = _control87(_MCW_EM, _MCW_EM);

    /* Disable and clear fp exceptions in the exception context */
    #if _WIN64
        ExceptionInfo->ContextRecord->FltSave.ControlWord = ctrl1;
        ExceptionInfo->ContextRecord->FltSave.StatusWord = 0;
    #else
        ExceptionInfo->ContextRecord->FloatSave.ControlWord = ctrl1;
        ExceptionInfo->ContextRecord->FloatSave.StatusWord = 0;
    #endif

    printf("#########Caught Ya#####!\n");

    return EXCEPTION_CONTINUE_EXECUTION;
}


int _tmain(int argc, _TCHAR* argv[])
{
    double a;

    /* enable fp exceptions*/
    _controlfp(0, _MCW_EM);

    /* Setup our unhandled exception filter */
    SetUnhandledExceptionFilter(myfunc);

    /* do something bad */
    a = 5.0 / zero;

    printf("a = %f\n",a);

    return 0;
}
#########Caught Ya#####!
a = -1.#IND00
#########Caught Ya#####!
#########Caught Ya#####!
#########Caught Ya#####!
#########Caught Ya#####!
#########Caught Ya#####!
#########Caught Ya#####!
...
#include "stdafx.h"
#include <float.h>
#include <Windows.h>
#include <xmmintrin.h>

double zero = 0.0;
LONG WINAPI myfunc(EXCEPTION_POINTERS * ExceptionInfo){
    /* clear the exception */
    unsigned int stat = _clearfp();

    /* disable all fp exceptions*/
    unsigned int ctrlwrd;
    errno_t err =  _controlfp_s(&ctrlwrd, _MCW_EM, _MCW_EM);

    /* Disable and clear the exceptions in the exception context */
    #if _WIN64
        /* Get current context to get the values of MxCsr register, which was
         * set by the calls to _controlfp above, we need to copy these into
         * the exception context so that exceptions really stay disabled.
         * References:
         *    https://msdn.microsoft.com/en-us/library/yxty7t75.aspx
         *    https://software.intel.com/en-us/articles/x87-and-sse-floating-point-assists-in-ia-32-flush-to-zero-ftz-and-denormals-are-zero-daz
         */
        CONTEXT myContext;
        RtlCaptureContext(&myContext);

        ExceptionInfo->ContextRecord->FltSave.ControlWord = ctrlwrd;
        ExceptionInfo->ContextRecord->FltSave.StatusWord = 0;
        ExceptionInfo->ContextRecord->FltSave.MxCsr = myContext.FltSave.MxCsr;
        ExceptionInfo->ContextRecord->FltSave.MxCsr_Mask = myContext.FltSave.MxCsr_Mask;
        ExceptionInfo->ContextRecord->MxCsr = myContext.MxCsr;
    #else
        ExceptionInfo->ContextRecord->FloatSave.ControlWord = ctrlwrd;
        ExceptionInfo->ContextRecord->FloatSave.StatusWord = 0;
    #endif

    printf("#########Caught Ya#####!\n");

    return EXCEPTION_CONTINUE_EXECUTION;
}

int _tmain(int argc, _TCHAR* argv[])
{
    double a;

    /* Enable fp exceptions */
    _controlfp_s(0, 0, _MCW_EM);

    /* Setup our unhandled exception filter */
    SetUnhandledExceptionFilter(myfunc);

    /* do something bad */
    a = 5.0 / zero;

    printf("a = %f\n",a);
    return 0;
}