使用 Windows 驱动程序中扩展的处理器功能
上次更新时间
- 2016 年 7 月
使用扩展处理器功能的 x86 和 x64 系统的 Windows 驱动程序必须在调用 KeSaveExtendedProcessorState 和 KeRestoreExtendedProcessorState 之间包装浮点计算,以避免在使用寄存器的并发应用程序中出现错误。
旧版 MMX/x87 寄存器
这些寄存器对应于XSTATE_MASK_LEGACY_FLOATING_POINT掩码,不适用于 x64 系统的驱动程序。 有关这些寄存器的详细信息,请参阅 在 WDM 驱动程序中使用浮点。
SSE 寄存器
这些寄存器对应于XSTATE_MASK_LEGACY_SSE标志,由 x64 编译器用于浮点运算。 使用这些寄存器的 x86 系统的驱动程序必须在使用前保存它们,方法是在 KeSaveExtendedProcessorState 调用中传递 XSTATE_MASK_LEGACY 或 XSTATE_MASK_LEGACY_SSE 标志,完成后,使用 KeRestoreExtendedProcessorState 还原它们。 这在 x64 系统上是不必要的,但并不有害。 有关这些寄存器的详细信息,请参阅 在 WDM 驱动程序中使用浮点。
AVX 寄存器
这些寄存器对应于XSTATE_MASK_GSSE或XSTATE_MASK_AVX掩码。 新的 x86 处理器(例如 Intel Sandy Bridge (以前的 Gesher) 处理器)支持 AVX 指令和寄存器集 (YMM0-YMM15) 。 在 Service Pack 1 (SP1) 、Windows Server 2008 R2 和较新版本的 Windows 中,x86 和 x64 版本的操作系统在线程 (和进程) 交换机之间保留 AVX 寄存器。 若要在内核模式下使用 AVX 寄存器, (x86 和 x64) 的驱动程序必须显式保存和还原 AVX 寄存器。 AVX 寄存器不能在中断服务例程中使用,并且默认情况下会关闭算术异常。
include ksamd64.inc
subttl "Set YMM State."
;++
;
; Routine Description:
;
; This routine loads the first four YMM registers with the state supplied.
;
; Arguments;
;
; rcx - Supplies a pointer to the values we want to load.
;
; Return Value:
;
; None
;
;--
LEAF_ENTRY SetYmmValues, _TEXT$00
vmovdqa ymm0, ymmword ptr[rcx + 0]
vmovdqa ymm1, ymmword ptr[rcx + 32]
vmovdqa ymm2, ymmword ptr[rcx + 64]
vmovdqa ymm3, ymmword ptr[rcx + 96]
ret
LEAF_END SetYmmValues, _TEXT$00
end
typedef DECLSPEC_ALIGN(32) struct _YMM_REGISTERS {
ULONG64 Ymm4Registers[16];
} YMM_REGISTERS, *PYMM_REGISTERS;
VOID
FASTCALL
SetYmmValues(
__in PYMM_REGISTERS YmmRegisterValues
);
NTSTATUS
DriverEntry (
__in PDRIVER_OBJECT DriverObject,
__in PUNICODE_STRING RegistryPath
)
{
NTSTATUS Status;
XSTATE_SAVE SaveState;
ULONG64 EnabledFeatures;
//
// Load the first 4 YMM registers as 4 vectors of 4 64-bit integers.
//
YMM_REGISTERS RegisterValues = { 0, 1, 2, 3, // YMM0
4, 5, 6, 7, // YMM1
8, 9, 10, 11, // YMM2
12, 13, 14, 15 }; // YMM3
//
// Check to see if AVX is available. Bail if it is not.
//
EnabledFeatures = RtlGetEnabledExtendedFeatures(-1);
if ((EnabledFeatures & XSTATE_MASK_GSSE) == 0) {
Status = STATUS_FAILED_DRIVER_ENTRY;
goto exit;
}
Status = KeSaveExtendedProcessorState(XSTATE_MASK_GSSE, &SaveState);
if (!NT_SUCCESS(Status)) {
goto exit;
}
__try {
SetYmmValues(&RegisterValues);
}
__finally {
KeRestoreExtendedProcessorState(&SaveState);
}
exit:
return Status;
}
相关主题
KeSaveExtendedProcessorState
KeRestoreExtendedProcessorState
在 WDM 驱动程序中使用浮点数