X86的体系架构里,整数运算和浮点运算是分开的。算术逻辑单元 (Arithmetic Logic Unit, ALU)是中央处理器(CPU)的执行单元,是所有中央处理器的核心组成部分,由"与门" "或门"构成的算术逻辑单元,主要功能是进行二进制的算术运算,如加减乘(不包括整数除法)。基本上,在所有现代CPU体系结构中,二进制都以二补数的形式来表示。浮点运算器(floating point unit,缩写FPU)是执行浮点运算的结构。一般是用电路来实现,应用在计算机芯片中。是整数运算器之后的一大发展,因为在浮点运算器发明之前,计算机中的浮点运算都是用整数运算来模拟的,效率十分低下。

下面这行语句,就是检测CPU是否有浮点运算器。

/* Check if an FPU is present */

NpxPresent = KiIsNpxPresent();

如果有有浮点运算器,就会返回TRUE,否则返回FALSEKiIsNpxPresent函数是使用汇编编写的,如下:

#001 .globl [email protected]

#002 .func [email protected]

#003 [email protected]:

#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

通过上面这段代码,就可以判断X86CPU是否有浮点运算器,如果没有浮点运算器,就可以使用整数来模拟了。如下图,就是显示FPU的存在:
reactos操作系统实现(18)

相关文章:

  • 2021-08-17
  • 2021-06-20
  • 2022-01-08
  • 2021-04-08
  • 2021-07-09
  • 2021-11-30
  • 2021-06-06
  • 2021-12-17
猜你喜欢
  • 2021-12-02
  • 2021-11-23
  • 2021-12-27
  • 2021-05-15
  • 2021-10-31
  • 2021-12-02
相关资源
相似解决方案