CPUID指令

来源:互联网 发布:算法问题实战策略pdf 编辑:程序博客网 时间:2024/05/16 17:26

介绍

cpuid就是一条读取CPU各种信息的一条指令,大概是从80486的某个版本开始就存在了。似乎是从80386开始,当CPU被RESET以 后,CPU会在EDX寄存器中返回一个32bits的CPU签名(Processor Identification Signature),但这时候CPU还没有CPUID这条指令,后来出现了这条指令后,软件无需以来CPU复位就可以读出这个CPU签名,同时还可以读 出很多CPU的相关信息。

CPUID这条指令,除了用于识别CPU(CPU的型号、家族、类型等),还可以读出CPU支持的功能(比如是否支持MMX,是否支持4MB的页等等), 内容的确是十分丰富。CPUID指令有两组功能,一组返回的是基本信息,另一组返回的是扩展信息

如何判断CPU是否支持CPUID指令

前面说过,大概是从80486开始才有的cpuid这个指令,是不是所有的80486家族CPU都有这个指令我也不是很清楚,但在EFLAGS中的bit 21可以识别CPU是否支持CPUID指令。
在8086和8088CPU中,FLAGS只有16位长,在80386CPU中,bit 21被保留未用,在支持CPUID指令的CPU中,这一位将为1

CPUID指令的执行方法

把功能代码放在EAX寄存器中,执行CPUID指令即可。例如:
mov eax, 1
cpuid

前面说过CPUID指令分为两组,一组返回基本信息,一组返回扩展信息,当执行返回基本信息的CPUID指令时,EAX中功能代码的bit 31为0,当执行返回扩展信息的CPUID指令时,EAX中的功能代码的bit 31为1。那么不管是那组功能,如何知道EAX中的功能代码最大可以是多少呢?根据Intel的说明,可以用如下方法:

mov eax, 0
cpuid
执行完CPUID指令后,EAX中返回的值就是返回基本信息时,功能代码的最大值,在执行CPUID指令要求返回基本信息时,EAX中的值必须小于或等于该值。

mov eax, 80000000h
cpuid
执行完CPUID指令后,EAX中返回的值就是返回扩展信息时,功能代码的最大值,在执行CPUID指令要求返回扩展信息时,EAX中的值必须小于或等于该值。

由于很多编译器都不能编译CPUID指令,所以了解CPUID指令的操作码是必要的,CPUID指令的操作码是:
0FA2h

注意:寄存器使用惯例

IA32指令集的寄存器使用惯例,这个惯例保证了函数调用时寄存器的值不会丢失或紊乱。

%eax、%edx和%ecx称为调用者保存寄存器,被调用者使用这三个寄存器时不必担心它们原来的值有没有保存下来,这是调用者自己应该负责的事情。

%ebx、%esi和%edi称为被调用者保存寄存器,被调用者如果想要使用它们,必须在开始时保存它们的值并在结束时恢复它们的值,一般通过压栈和出栈来实现。

AMD64

寄存器 RAX、RCX、RDX、R8、R9、R10、R11 被视为易失的,并且必须在函数调用时视为已销毁(除非通过全程序优化等分析被认定为安全的)。

寄存器 RBX、RBP、RDI、RSI、RSP、R12、R13、R14 和 R15 被视为非易失的,必须由使用它们的函数进行保存和还原

原创粉丝点击