下面这行语句,就是检测CPU是否有浮点运算器。
/* Check if an FPU is present */
NpxPresent = KiIsNpxPresent();
如果有有浮点运算器,就会返回TRUE,否则返回FALSE。KiIsNpxPresent函数是使用汇编编写的,如下:
#001 .globl _KiIsNpxPresent@0
#002 .func KiIsNpxPresent@0
#003 _KiIsNpxPresent@0:
#004
#005 /* Save stack */
#006 push ebp
#007
#008 /* Get CR0 and mask out FPU flags */
#009 mov eax, cr0
#010 and eax, ~(CR0_MP + CR0_TS + CR0_EM + CR0_ET)
获取CR0寄存器的值。
#011
#012 /* Initialize the FPU and assume FALSE for return */
#013 xor edx, edx
#014 fninit
设置返回值为FALSE,并初始化浮点运算器。
#015
#016 /* Save magic value on stack */
#017 mov ecx, 0x42424242
#018 push ecx
#019
#020 /* Setup stack for FPU store */
#021 mov ebp ,esp
#022 fnstsw [ebp]
保存浮点控制寄存器值到栈里。
#023
#024 /* Now check if our magic got cleared */
#025 cmp byte ptr [ebp], 0
#026 jnz NoFpu
上面判断浮点控制寄存器值是否保存出来,如果清空为0,说明保存出来,有浮点运算器,否则就是没有。
#027
#028 /* Enable FPU, set return to TRUE */
#029 or eax, CR0_ET
#030 mov edx, 1
打开浮点运算器,并设置返回值为TRUE。
#031
#032 /* If this is a 486 or higher, enable INT 16 as well */
#033 cmp dword ptr fs:KPCR_PRCB_CPU_TYPE, 3
#034 jbe NoFpu
#035 or eax, CR0_NE
#036
#037 NoFpu:
#038 /* Set emulation enabled during the first boot phase and set the CR0 */
#039 or eax, (CR0_EM + CR0_TS)
#040 mov cr0, eax
#041
#042 /* Restore stack */
#043 pop eax
#044 pop ebp
#045
#046 /* Return true or false */
#047 mov eax, edx
#048 ret
#049 .endfunc