提问人:daniel 提问时间:7/19/2023 更新时间:7/25/2023 访问量:114
在 IRQL 中使用浮点运算high_level
using floating-point operations at high_level irql
问:
在HIGH_LEVEL IRQL 执行的内核例程中,我一直在尝试通过直接调用 FXSAVE 和 FXRSOR 来管理浮点状态。由于 KeSaveExtendedProcessorState 和 KeRestoreExtendedProcessorState 在此级别不可用,因此我不得不求助于此方法。
这是我目前的实现:
在汇编代码中,我定义了两个过程 SaveFxState 和 RestoreFxState:
SaveFxState PROC
; Save the floating point state
mov rax, rcx
fxsave [rax]
ret
SaveFxState ENDP
RestoreFxState PROC
; Restore the floating point state
mov rax, rcx
fxrstor [rax]
ret
RestoreFxState ENDP
这些过程通过外部“C”链接到我的 C++ 代码公开:
extern "C" {
void SaveFxState(void* saveArea);
void RestoreFxState(void* saveArea);
}
我按如下方式使用这些过程:
FXSAVE_FORMAT g_FxSaveArea;
SaveFxState(&g_FxSaveArea);
// Floating-point operations are here
RestoreFxState(&g_FxSaveArea);
谁能确认这种方法对于管理 IRQL 的浮点状态是否正确和安全HIGH_LEVEL?我将不胜感激任何改进的见解或建议。
答:
0赞
daniel
7/24/2023
#1
我一直在研究内核编程,需要执行浮点运算。在内核模式下执行此操作的挑战之一是在高级 irql 中保留浮点和 SIMD 状态。我想分享一种我发现使用_fxsave64和_fxrstor64内部函数有效的方法。
先决条件: 确保您有充分的理由在内核中使用浮点,因为它可能会引入难以调试的问题。
溶液: 首先,声明一个缓冲区来保存 FPU 状态。此缓冲区应为 16 字节
aligned:
__declspec(align(16)) BYTE FpuState[512]; // Ensure the memory area is 16-byte aligned
接下来,将浮点代码包装在 _fxsave64 和 _fxrstor64 之间:
void KernelFunctionWithFPUOperations()
{
_fxsave64(FpuState);
__try {
DoFloatingPointCalculation();
}
__finally {
_fxrstor64(FpuState);
}
}
警告:
- 始终确保缓冲区的对齐。
- 在内核模式下谨慎使用结构化异常处理。有一些特殊的注意事项需要注意。
- 除非绝对必要,否则通常不建议在内核中使用浮点运算。确保您已实施必要的预防措施。
我希望这对任何面临类似挑战的人有所帮助!欢迎反馈或进一步的见解!
上一个:获取函数的浮点数的错误返回值
评论