【汇编优化】之CPUID获取x86处理器信息

###1、CPUID - CPU 标识

操作码 指令 说明
OF A2 CPUID 按照最初输入 EAX 寄存器的值,将处理器标识与功能信息返回给 EAX、EBX、ECX 及 EDX 寄存器。

说明
在寄存器 EAX、EBX、ECX 及 EDX 中提供处理器标识信息。这些信息指出英特尔是处理器的生产商,并给出处理器的系列、型号、分级、功能信息以及缓存信息。在 EAX 寄存器中加载的输入值确定返回哪些信息,具体如下表所示:

CPUID 指令返回的信息
【汇编优化】之CPUID获取x86处理器信息_第1张图片
EFLAGS 寄存器中的 ID 标志(位 21)指示是否支持 CPUID 指令。如果软件过程可以设置与清除此标志,则表示执行此过程的处理器支持 CPUID 指令。

CPUID 指令返回的信息分为两组:基本信息与扩展功能信息。在 EAX 寄存器中输入 0 到 3(根据 IA-32 处理器类型)的值时,返回基本信息;输入 80000000H 到 80000004H 的值时,返回扩展功能信息。扩展功能 CPUID 信息是在奔腾® 4 处理器中引入的,

早期的 IA-32 处理器并不提供。“IA-32 处理器的最大 CPUID 源操作数”表显示:对于实现 CPUID 指令的每个 IA-32 处理器系列,针对基本信息与扩展功能信息,处理器可识别的 CPUID 指令最大输入值。

IA-32 处理器的最大 CPUID 源操作数
【汇编优化】之CPUID获取x86处理器信息_第2张图片

对于特定的处理器,如果输入大于“CPUID 指令返回的信息”中显示的值,则返回最大有用基本信息值对应的信息。例如,如果将 5 输入奔腾 4 处理器的 EAX,则返回输入值 2 对应的信息。返回扩展功能信息的输入值(目前,这些值是 80000000H 到 80000004H)属于此规则的例外情况。对于奔腾 4 处理器,输入 80000005H 以上的值时,将返回输入值 2 对应的信息。

CPUID 指令可以在任何特权级别执行,以序列化指令执行。序列化指令执行确保在获取与执行下一条指令之前,前面的指令对标志、寄存器及内存的任何修改都已经完成(请参阅“IA-32 英特尔® 体系结构软件开发人员手册”第 3 卷第 7 章中的“序列化指令”)。

EAX 寄存器中的输入值为 0 时,处理器返回 CPUID 指令可识别的、用于返回基本 CPUID 信息的 EAX 寄存器最大值(请参阅表格“IA-32 处理器的最大 CPUID 源操作数”)。供应商标识字符串在 EBX、EDX 及 ECX 寄存器中返回。对于英特尔® 处理器,供应商标识字符串是 “GenuineIntel”,如下所示:

EBX ←756e6547h(* "Genu",G 位于 BL 的低位半字节 *)
EDX ←49656e69h(* "ineI",i 位于 DL 的低位半字节 *)
ECX ←6c65746eh(* "ntel",n 位于 CL 的低位半字节 *)

输入值为 1 时,处理器将版本信息返回给 EAX 寄存器(请参阅“EAX 寄存器中的版本信息”)。版本信息由 IA-32 处理器系列标识、型号标识、分级标识以及处理器类型组成。英特尔奔腾 4 系列中第一个处理器的型号、系列及处理器类型如下:

  • 型号 - 0000B

  • 系列 - 1111B

  • 处理器类型 - 00B

“处理器类型字段”表给出可用的处理器类型。英特尔会根据需要发布分级标识信息。

EAX 寄存器中的版本信息
【汇编优化】之CPUID获取x86处理器信息_第3张图片

处理器类型字段
【汇编优化】之CPUID获取x86处理器信息_第4张图片

如果系列与/或型号字段中的值等于或超过 FH,CPUID 指令将在 EAX 寄存器中额外生成两个字段:扩展系列字段与扩展型号字段。这里,型号字段或系列字段中的值 FH 分别表示扩展型号或系列字段是有效的。超出 FH 的系列与型号数值的范围是 0FH 到 FFH,最低有效十六进制数总是 FH。

如需有关识别早期 IA-32 处理器的详细信息,请参阅 AP-485“英特尔处理器标识与 CPUID 指令(订购编号 241618),以及“IA-32 英特尔体系结构软件开发人员手册”第 1 卷第 13 章。

EAX 中的输入值为 1 时,会将三项彼此无关的信息返回给 EBX 寄存器:

  • 商标索引(EBX 的低位字节):此数字提供商标字符串表格的入口,该表格包含 IA-32 处理器的商标字符串。如需有关商标索引用途的详细信息,请参阅本指令说明中的后文“商标标识”。此字段在奔腾® III 至强™ 处理器中引入。

  • CLFLUSH 指令缓存线大小(EBX 的第二个字节)- 此数字表示 CLFLUSH 指令清除的缓存线大小,增量为 8 字节。此字段在奔腾 4 处理器中引入。

  • 局部 APIC ID(EBX 的高位字节)- 此数字是一个 8 位标识,在加电期间赋给处理器上的局部 APIC。此字段在奔腾 4 处理器中引入。

EAX 中的输入值为 1 时,功能信息返回给 EDX 寄存器(请参阅“EDX 寄存器中的功能信息”)。功能位可供操作系统或应用程序代码用于确定处理器可以提供哪些 IA-32 体系结构功能。“返回 EDX 寄存器的 CPUID 功能标志”表显示 EDX 寄存器中功能标志的编码。对于当前返回给 EDX 的所有功能标志,1 表示支持相应的功能。软件需要将 Intel 标为供应商,才可以正确解释功能标志。对于未来的功能标志,软件不应认为 1 就表示提供某项功能。

ECX EDX 寄存器中的功能信息
【汇编优化】之CPUID获取x86处理器信息_第5张图片
【汇编优化】之CPUID获取x86处理器信息_第6张图片

缓存与 TLB 描述符的编码

输入值为 2 时,处理器将关于处理器内部缓存与 TLB 的信息返回给 EAX、EBX、ECX 及 EDX 寄存器。这些寄存器的编码如下:

  • 寄存器 EAX 的最低有效字节(寄存器 AL)表示 CPUID 指令必须使用输入值 2 执行的次数,以获取关于处理器缓存与 TLB 的完整描述。奔腾 4 处理器系列的第一个处理器将返回 1。

  • 每个寄存器的最高有效位(位 31)表示寄存器是包含有效信息(设置为 0)还是保留的(设置为 1)。

  • 如果寄存器包含有效信息,则信息包含在 1 个字节的描述符中。“缓存与 TLB 描述符的编码”表显示这些描述符的编码。请注意,EAX、EBX、ECX 及 EDX 寄存器中描述符的顺序没有定义;也就是说,特定的字节不一定包含特定缓存或 TLB 类型的描述符。描述符可以按任何顺序出现。
    【汇编优化】之CPUID获取x86处理器信息_第7张图片
    奔腾 4 系列的第一个处理器使用输入值 2 执行 CPUID 指令时,将返回关于缓存与 TLB 的以下信息:

EAX 66 5B 50 01H

EBX 0H

ECX 0H

EDX 00 7A 70 00H

这些值的含义如下:

  • 寄存器 EAX 的最低有效字节(字节 0)设置为 01H,表示只需使用输入值 2 执行 CPUID 指令一次,就可以检索到关于处理器缓存与 TLB 的完整信息。

  • 所有四个寄存器(EAX、EBX、ECX 及 EDX)的最高有效位都设置为 0,表示每个寄存器都包含 1 个字节的有效描述符。

  • 寄存器 EAX 的字节 1、2 及 3 表示处理器包含以下内容:

  • 50H - 64 项指令 TLB,用于映射 4 KB 与 2 MB 或 4 MB 页。

  • 5BH - 64 项数据 TLB,用于映射 4 KB 与 4 MB 页。

  • 66H - 8 KB 一级数据缓存,4 路缓存线组联合,64 字节缓存线大小。

  • 寄存器 EBX 与 ECX 中的描述符有效,但包含空描述符。

  • 寄存器 EDX 的字节 0、1 及 2 表示处理器包含以下内容:

  • 00H - 空描述符。

  • 70H - 12 KB 一级代码缓存,4 路缓存线组联合,64 字节缓存线大小。

  • 7AH - 256 KB 二级缓存,8 路缓存线组联合,分扇区的 64 字节缓存线大小。

  • 00H - 空描述符。

商标标识
为便于使用 CPUID 指令确定 IA-32 处理器的商标,这里提供两个功能:商标索引与商标字符串。

商标索引是从奔腾 III 至强处理器开始新增到 CPUID 指令的,将来的 IA-32 处理器(包括奔腾 4 处理器)也将包含此功能。商标索引提供商标标识表格的入口,此表格由系统软件在内存中维护,可以通过系统级与用户级代码进行访问。在这个表格中,每个商标索引与一个 ASCII 商标字符串关联,此字符串用于确定处理器的正式英特尔系列与型号(例如,“英特尔奔腾III 处理器”)。

EAX 寄存器中的值为 1 时,执行 CPUID 指令会将商标索引返回给 EBX 的低位字节。接着,软件就可以使用此索引,在商标识别表格中确定处理器的商标识别字符串。此表格的第一个项目(商标索引 0)是保留的,以便向后兼容不支持商标标识功能的处理器。在表格“商标索引与 IA-32 处理器商标字符串之间的映射”中,列出了当前有处理器

商标标识字符串与之关联的商标索引。

建议:

  1. 将商标标识表格中包含的所有保留项目,与指明该索引是保留供未来英特尔处理器使用的商标字符串相关联。

  2. 将软件准备成能够恰当处理保留的商标索引。

商标索引与 IA-32 处理器商标字符串之间的映射
【汇编优化】之CPUID获取x86处理器信息_第8张图片
† 表示在奔腾 III 至强处理器之后引入的这些处理器版本。

商标字符串功能是 CPUID 指令的扩展,在奔腾 4 处理器中引入。通过使用此功能,CPUID 指令可以将 ASCII 商标标识字符串与处理器的最高工作频率返回给 EAX、EBX、ECX 及 EDX 寄存器。(请注意,返回的频率是处理器经检验合格的最高工作频率,而不是处理器的当前工作频率)。

要使用商标字符串功能,必须执行 CPUID 指令三次:第一次在 EAX 寄存器中输入值 8000002H,第二次输入值 80000003,第三次输入值 80000004H。

在体系结构上,商标字符串定义成 48 字节长:头 47 个字节包含 ASCII 字符,第 48 个字节定义为空 (0)。为了简化实现,字符串可能为右对齐(前面加空格)。对于每个输入值(EAX 为 80000002H、80000003H 或 80000004H),CPUID 指令将 16 字节的商标字符串返回给 EAX、EBX、ECX 及 EDX 寄存器。处理器的实现可能会返回少于 47 个的 ASCII 字符,在这种情况下,字符串以空值结尾,处理器将返回 CPUID 输入值为 80000002H、80000003H 及 80000004H 的有效数据。

“第一个奔腾 4 处理器返回的处理器商标字符串”表显示奔腾 4 处理器系列的第一个处理器返回的商标字符串。

备注
商标字符串中给出频率时,它是处理器的最高合格频率,而不是处理器当前运行的实际频率。以下操作程序可用于检测商标字符串功能:

  1. 使用 EAX 的输入值 80000000H 执行 CPUID 指令。

  2. 如果 ((EAX_Return_Value) AND (80000000H) ≠0),则处理器支持扩展的 CPUID 功能,并且 EAX 包含支持的最大扩展功能输入值。

  3. 如果 EAX_Return_Value ≥80000004H,则 CPUID 指令支持商标字符串功能。

第一颗奔腾® 4 处理器返回的处理器商标字符串
【汇编优化】之CPUID获取x86处理器信息_第9张图片

要使用 CPUID 指令确定 IA-32 处理器,商标标识软件
应该使用以下商标标识技术(按优先级的降序排列):

  • 处理器商标字符串

  • 处理器商标索引与软件提供的商标字符串表格。

  • 基于由 CPUID 指令返回的类型、系列、型号、分级以及缓存信息组成的结构的表格。

IA-32 体系结构兼容性。

Intel486 处理器的早期型号以及早于 Intel486 处理器任何 IA-32 处理器都不支持 CPUID 指令。

操作

CASE (EAX) OF
EAX =0:
EAX ←highest basic function input value understood by CPUID;
EBX ←Vendor identification string;
EDX ←Vendor identification string;
ECX ←Vendor identification string;
BREAK;

EAX =1H:
EAX[3:0] ←Stepping ID;
EAX[7:4] ←Model;
EAX[11:8] ←Family;
EAX[13:12] ←Processor type;
EAX[15:14] ←Reserved;
EAX[19:16] ←Extended Model;
EAX[23:20] ←Extended Family;
EAX[31:24] ←Reserved;
EBX[7:0] ←Brand Index;
EBX[15:8] ←CLFLUSH Line Size;
EBX[16:23] ←Reserved;
EBX[24:31] ←Initial APIC ID;
ECX ←Reserved;
EDX ←Feature flags; (* See Figure 3-4 *)
BREAK;

EAX =2H:
EAX ←Cache and TLB information;
EBX ←Cache and TLB information;
ECX ←Cache and TLB information;
EDX ←Cache and TLB information;
BREAK;

EAX =3H:
EAX ←Reserved;
EBX ←Reserved;
ECX ←ProcessorSerialNumber[31:0];
(* Pentium III processors only, otherwise reserved *)
EDX ←ProcessorSerialNumber[63:32];
(* Pentium III processors only, otherwise reserved *
BREAK;

EAX =80000000H:
EAX ←highest extended function input value understood by CPUID;
EBX ←Reserved;
ECX ←Reserved;
EDX ←Reserved;
BREAK;

EAX =80000001H:
EAX ←Extended Processor Signature and Feature Bits (*Currently Reserved*);
EBX ←Reserved;
ECX ←Reserved;
EDX ←Reserved;
BREAK;

EAX =80000002H:
EAX ←Processor Name;
EBX ←Processor Name;
ECX ←Processor Name;
EDX ←Processor Name;
BREAK;

EAX =80000003H:
EAX ←Processor Name;
EBX ←Processor Name;
ECX ←Processor Name;
EDX ←Processor Name;
BREAK;

EAX =80000004H:
EAX ←Processor Name;
EBX ←Processor Name;
ECX ←Processor Name;
EDX ←Processor Name;
BREAK;
DEFAULT: (* EAX >highest value recognized by CPUID *)
EAX ←Reserved; (* undefined*)
EBX ←Reserved; (* undefined*)
ECX ←Reserved; (* undefined*)
EDX ←Reserved; (* undefined*)
BREAK;

ESAC;
影响的标志
无。
异常(所有操作模式)
无。

备注 备注
对于不支持 CPUID 指令的早期 IA-32 处理器,执行此指令会导致生成操作码无效 (#UD) 异常。

###2、看处理器是否支持CPUID的方法

# Here’s a test for the presence of the CPUID instruction
		pushfl				# copy EFLAGS contents
		pop	%eax			#  to accumulator register
		mov	%eax, %edx		# save a duplicate image
		btc	$21, %eax		# toggle the ID-bit (bit 21)
		push	%eax			# copy revised contents
		popfl				#  back into EFLAGS
		pushfl				# copy EFLAGS contents
		pop	%eax			#  back into accumulator
		xor	%edx, %eax		# do XOR with prior value
		bt	$21, %eax		# did ID-bit get toggled?
		jc	y_cpuid			# yes, can execute ‘cpuid’
		jmp	n_cpuid			# else ‘cpuid’ unimplemented

这里写图片描述
【汇编优化】之CPUID获取x86处理器信息_第10张图片
这里写图片描述

参考网址:https://software.intel.com/sites/default/files/managed/a4/60/325383-sdm-vol-2abcd.pdf P300
https://www.cs.usfca.edu/~cruse/cs630f06/lesson23.ppt
https://wenku.baidu.com/view/0346655a804d2b160b4ec071
https://360.ggws.net/search?q=btc+eax,21&newwindow=1&ei=vpD2WvStN4Ol8AWt1bPwBA&start=10&sa=N&biw=1920&bih=949
https://www.cnblogs.com/this-543273659/archive/2012/02/25/2367907.html
https://wenku.baidu.com/view/207c667d5acfa1c7aa00cc31.html

你可能感兴趣的:(【汇编优化】,算法优化)