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