En la arquitectura x86 , la instrucción CPUID (identificada por un CPUID
código de operación ) es una instrucción complementaria del procesador (su nombre deriva de CPU Identification) que permite al software descubrir detalles del procesador. Fue introducido por Intel en 1993 con el lanzamiento de los procesadores 486 mejorados con Pentium y SL . [1]
Un programa puede utilizar para determinar el tipo de procesador y si se implementan CPUID
funciones como MMX / SSE .
Antes de la disponibilidad general de la CPUID
instrucción, los programadores escribían código de máquina esotérico que explotaba diferencias menores en el comportamiento de la CPU para determinar la marca y el modelo del procesador. [2] [3] Con la introducción del procesador 80386, EDX al reiniciar indicaba la revisión, pero esto solo era legible después del reinicio y no había una forma estándar para que las aplicaciones leyeran el valor.
Fuera de la familia x86, la mayoría de los desarrolladores todavía deben utilizar procesos esotéricos (que implican sincronización de instrucciones o activadores de fallas de CPU) para determinar las variaciones en el diseño de la CPU que están presentes.
En la familia Motorola 680x0, que nunca tuvo CPUID
instrucciones de ningún tipo, ciertas instrucciones específicas requerían privilegios elevados. Estos podrían usarse para diferenciar a varios miembros de la familia de CPU. En el Motorola 68010 se privilegió la instrucción MOVE de SR . Este notable cambio en las instrucciones (y en la máquina de estados) permitió que el 68010 cumpliera con los requisitos de virtualización de Popek y Goldberg . Debido a que el 68000 ofrecía un MOVE sin privilegios desde SR, las 2 CPU diferentes podían diferenciarse mediante la activación de una condición de error de CPU.
Si bien la CPUID
instrucción es específica de la arquitectura x86, otras arquitecturas (como ARM) a menudo proporcionan registros en el chip que se pueden leer de maneras prescritas para obtener el mismo tipo de información proporcionada por la CPUID
instrucción x86.
El CPUID
código de operación es 0F A2
.
En lenguaje ensamblador , la CPUID
instrucción no toma parámetros ya que CPUID
implícitamente utiliza el registro EAX para determinar la categoría principal de información devuelta. En la terminología más reciente de Intel, esto se denomina hoja CPUID. CPUID
debe llamarse EAX = 0
primero, ya que esto almacenará en el registro EAX el parámetro de llamada EAX más alto (hoja) que implementa la CPU.
Para obtener información de función extendida CPUID
se debe llamar con el bit más significativo de EAX configurado. Para determinar el parámetro de llamada de función extendida más alto, llame CPUID
con EAX = 80000000h
.
Las hojas de CPUID superiores a 3 pero inferiores a 80000000 son accesibles solo cuando los registros específicos del modelo tienen IA32_MISC_ENABLE.BOOT_NT4 [bit 22] = 0 (que es así de forma predeterminada). Como sugiere el nombre, Windows NT 4.0 hasta SP6 no arrancaba correctamente a menos que se estableciera este bit, [4] pero las versiones posteriores de Windows no lo necesitan, por lo que se puede suponer que las hojas básicas mayores a 4 son visibles en los sistemas Windows actuales. A partir de septiembre de 2023 [actualizar], las licencias básicas válidas llegan hasta las 20h, pero la información devuelta por algunas licencias no se divulga en la documentación disponible públicamente, es decir, están "reservadas".
Algunas de las hojas agregadas más recientemente también tienen subhojas, que se seleccionan mediante el registro ECX antes de llamar CPUID
.
Esto devuelve la cadena de identificación del fabricante de la CPU: una cadena ASCII de doce caracteres almacenada en EBX, EDX, ECX (en ese orden). El parámetro de llamada básico más alto (el valor más grande que se puede establecer en EAX antes de llamar CPUID
) se devuelve en EAX.
Aquí hay una lista de procesadores y la función más alta implementada.
Las siguientes son cadenas de identificación de fabricantes de procesadores conocidos:
"AMDisbetter!"
– primeras muestras de ingeniería del procesador AMD K5"AuthenticAMD"
– AMD"CentaurHauls"
– IDT WinChip/ Centaur (incluidas algunas CPU VIA y Zhaoxin)"CyrixInstead"
– Cyrix /primeros STMicroelectronics e IBM"GenuineIntel"
–Intel _"GenuineIotel"
– Intel (raro) [5]"TransmetaCPU"
– Transmeta"GenuineTMx86"
– Transmeta"Geode by NSC"
– Semiconductor Nacional"NexGenDriven"
– NexGen"RiseRiseRise"
- Elevar"SiS SiS SiS "
– SiS"UMC UMC UMC "
– UMC"VIA VIA VIA "
- A TRAVÉS DE"Vortex86 SoC"
– DM&P Vórtice86" Shanghai "
–Zhaoxin _"HygonGenuine"
– Hygón"Genuine RDC"
– RDC Semiconductor Co. Ltd. [6]"E2K MACHINE"
– MCST Elbrús [7]Las siguientes son cadenas de identificación utilizadas por los núcleos de CPU software de código abierto :
"GenuineAO486"
– CPU ao486 (antigua) [8] [9]"MiSTer AO486"
– CPU ao486 (nueva) [10] [9]"GenuineIntel"
– núcleo v586 [11] (esto es idéntico a la cadena de ID de Intel)Las siguientes son cadenas de ID conocidas de máquinas virtuales:
"bhyve bhyve "
– bhyve"KVMKVMKVM\0\0\0"
– KVM , \0 indica un carácter ASCII NUL"TCGTCGTCGTCG"
– QEMU"Microsoft Hv"
– Microsoft Hyper-V o Windows Virtual PC"MicrosoftXTA"
– Microsoft x86 a ARM [12]" lrpepyh vr"
– Parallels (posiblemente debería ser "prl hyperv", pero está codificado como "lrpepyh vr" debido a una falta de coincidencia de endianidad ) [ cita necesaria ]"VMwareVMware"
– VMware"XenVMMXenVMM"
– XenHVM"ACRNACRNACRN"
– Proyecto ACRN" QNXQVMBSQG "
– Hipervisor QNX"GenuineIntel"
– Manzana Rosetta 2 [13]"VirtualApple"
– Versiones más recientes de Apple Rosetta 2Por ejemplo, en un procesador GenuineIntel, los valores devueltos en EBX son 0x756e6547, EDX son 0x49656e69 y ECX son 0x6c65746e. El siguiente código de ejemplo muestra la cadena de ID del proveedor, así como el parámetro de llamada más alto que implementa la CPU.
.intel_syntax sin prefijo .texto.m0: .string "CPUID: %x\n" .m1: .string "Número de función básica más grande implementado: %i\n" .m2: .string "ID de proveedor: %s\n" .globl principal principal:empujar r12 movimiento eax , 1 sub rsp , 16 CPU le rdi , .m0 [ rasgar ] mov esi , eax llamar a printfmovimiento eax , 0 CPUle rdi , .m1 [ rasgar ] mov esi , eax mov r12d , edx movimiento ebp , ecx llamar a printf mov 3 [ rsp ], ebx lea rsi , 3 [ rsp ] le rdi , .m2 [ rasgar ] movimiento 7 [ rsp ], r12d mov 11 [ rsp ], rebp llamar a printfañadir rsp , 16 pop r12 retirado .sección .note.GNU - pila , " " , @progbits
En algunos procesadores, es posible modificar la cadena de ID del fabricante informada por CPUID (EAX = 0) escribiendo una nueva cadena de ID en MSR ( registros específicos del modelo ) particulares usando la WRMSR
instrucción. Esto se ha utilizado en procesadores que no son Intel para habilitar funciones y optimizaciones que se han deshabilitado en el software para CPU que no devuelven la GenuineIntel
cadena de ID. [14] Los procesadores que se sabe que poseen tales MSR incluyen:
Esto devuelve la información de paso , modelo y familia de la CPU en el registro EAX (también llamado firma de una CPU), indicadores de funciones en los registros EDX y ECX, e información de funciones adicionales en el registro EBX. [21]
En octubre de 2023, se conocen los siguientes ID de familia de procesadores x86: [23]
CPUID
instrucción; sin embargo, devuelve el ID de familia 3h
en el valor de reinicio de EDX.8h
se evitó deliberadamente para la familia de procesadores Pentium 4 debido a la incompatibilidad con Windows NT 4.0. [33]La información del procesador y los indicadores de características son específicos del fabricante, pero generalmente otros fabricantes utilizan los valores de Intel por razones de compatibilidad.
CPUID
con un índice de hoja (EAX) mayor que 0 puede dejar EBX y ECX sin modificar, manteniendo sus valores anteriores. Por este motivo, se recomienda poner a cero EBX y ECX antes de ejecutar CPUID
con un índice de hoja de 1.Los procesadores que exhiben este comportamiento incluyen Cyrix MII [37] e IDT WinChip 2. [38]
CentaurHauls
y GenuineTMx86
) RiseRiseRise
, la CMPXCHG8B
instrucción siempre es compatible; sin embargo, es posible que el bit de característica de la instrucción no esté configurado. Esta es una solución para un error en Windows NT. [39]AuthenticAMD
Familia 5 Modelo 0), EDX bit 9 solía indicar compatibilidad con PGE. Esto se movió al bit 13 desde K5 Modelo 1 en adelante. [40]GenuineIntel
Familia 6 Modelo 1), el bit 11 de EDX no es válido: el bit que configuró, pero las instrucciones SYSENTER
y SYSEXIT
no son compatibles con el Pentium Pro. [42]FCMOV
y FCOMI
las instrucciones solo están disponibles si la FPU x87 integrada también está presente (indicada por EDX bit 0).119h
( BBL_CR_CTL
) en 1. Al hacerlo, CPUID.(EAX=1):EDX[bit 18] devolverá 0.En la documentación anterior, este bit a menudo aparece como un indicador de " tecnología Hyper-Threading " [47] ; sin embargo, si bien este indicador es un requisito previo para la compatibilidad con Hyper-Threading, no indica por sí solo compatibilidad con Hyper-Threading y tiene Se ha configurado en muchas CPU que no cuentan con ningún tipo de tecnología de subprocesos múltiples. [48]
Los campos reservados deben enmascararse antes de utilizarlos con fines de identificación del procesador.
Esto devuelve una lista de descriptores que indican capacidades de caché y TLB en los registros EAX, EBX, ECX y EDX.
En los procesadores que admiten esta hoja, llamar CPUID
con EAX=2 hará que el byte inferior de EAX se establezca en 01h
y los 15 bytes restantes de EAX/EBX/ECX/EDX se llenen con 15 descriptores, un byte cada uno. Estos descriptores proporcionan información sobre las cachés, los TLB y la captación previa del procesador. Por lo general, se trata de un caché o TLB por descriptor, pero algunos valores de descriptor también proporcionan otra información; en particular, 00h
se usa para un descriptor vacío, FFh
indica que la hoja no contiene información de caché válida y que se debe usar la hoja 4h en su lugar. e FEh
indica que la hoja no contiene información TLB válida y que en su lugar se debe utilizar la hoja 18h. Los descriptores pueden aparecer en cualquier orden.
Para cada uno de los cuatro registros (EAX,EBX,ECX,EDX), si se establece el bit 31, no se debe considerar que el registro contiene descriptores válidos (por ejemplo, en Itanium en modo IA-32, CPUID(EAX=2) devuelve 80000000h
en EDX: esto debe interpretarse en el sentido de que EDX no contiene información válida, no que contiene un caché L2 de 512 K).
La siguiente tabla proporciona, para valores de descriptor conocidos, una descripción condensada de la caché o TLB indicada por ese valor de descriptor (u otra información, cuando corresponda). Los sufijos utilizados en la tabla son:
10h
, 15h
, 1Ah
, 88h
, 89h
, 8Ah
, 90h
, están documentados solo para el modo de operación IA-32 96h
de Itanium . [52]9Bh
26h
27h
28h
81h
81h
39h-3Eh
73h
39h
49h
indica un caché de nivel 3 en GenuineIntel
las CPU de la familia 0Fh Modelo 6 (Xeon basado en Pentium 4) y un caché de nivel 2 en otras CPU.4Fh
. Los procesadores que utilizan este descriptor (Intel Atom "Bonnell" [55] ) figuran en otros lugares con una ITLB de 32 entradas totalmente asociativa. [56]CyrixInstead
y Geode by NSC
), los descriptores 70h
tienen 80h
un significado diferente: [57]70h
indica un TLB asociativo de conjunto de 4 vías de datos e instrucciones compartidas de 32 entradas con un tamaño de página de 4K.80h
indica una caché L1 de datos e instrucciones compartidas de 16 KB con asociatividad de conjuntos de 4 vías y un tamaño de línea de caché de 16 bytes.76h
aparece como un caché L2 de 1 MByte en la revisión 37 de Intel AP-485, [58] pero como una instrucción TLB en la revisión 38 y toda la documentación posterior de Intel.77h
abc 7Eh
están 8Dh
documentados solo para el modo de operación IA-32 de Itanium 2 . [60]B1h
, la capacidad de TLB es de 8 elementos cuando se usan páginas de 2 MBytes, pero se reduce a 4 elementos cuando se usan páginas de 4 MBytes.Esto devuelve el número de serie del procesador. El número de serie del procesador se introdujo en Intel Pentium III , pero debido a cuestiones de privacidad, esta característica ya no se implementa en modelos posteriores (el bit de característica de PSN siempre está borrado). Los procesadores Efficeon y Crusoe de Transmeta también ofrecen esta característica. Sin embargo, las CPU AMD no implementan esta característica en ningún modelo de CPU.
Para las CPU Intel Pentium III, el número de serie se devuelve en los registros EDX:ECX. Para las CPU Transmeta Efficeon, se devuelve en los registros EBX:EAX. Y para las CPU Transmeta Crusoe, se devuelve únicamente en el registro EBX.
Tenga en cuenta que la función del número de serie del procesador debe estar habilitada en la configuración del BIOS para poder funcionar.
Estas dos hojas se utilizan para la topología del procesador (subproceso, núcleo, paquete) y la enumeración de la jerarquía de caché en los procesadores Intel multinúcleo (e hiperproceso). [64] A partir de 2013, [actualizar]AMD no utiliza estas hojas, pero tiene formas alternativas de realizar la enumeración central. [sesenta y cinco]
A diferencia de la mayoría de las otras hojas de CPUID, la hoja Bh devolverá diferentes valores en EDX dependiendo del procesador lógico que ejecute la instrucción CPUID; el valor devuelto en EDX es en realidad la identificación x2APIC del procesador lógico. Sin embargo, el espacio de identificación x2APIC no se asigna continuamente a procesadores lógicos; Puede haber lagunas en el mapeo, lo que significa que algunos identificadores x2APIC intermedios no necesariamente corresponden a ningún procesador lógico. En los otros registros se proporciona información adicional para asignar los identificadores de x2APIC a los núcleos. Aunque la hoja Bh tiene subhojas (seleccionadas por ECX como se describe más adelante), el valor devuelto en EDX solo se ve afectado por el procesador lógico en el que se ejecuta la instrucción, pero no por la subrehoja.
La topología de procesador(es) expuesta por la hoja Bh es jerárquica, pero con la extraña advertencia de que el orden de los niveles (lógicos) en esta jerarquía no corresponde necesariamente al orden en la jerarquía física ( SMT /núcleo/paquete) . Sin embargo, cada nivel lógico se puede consultar como una subhoja ECX (de la hoja Bh) para determinar su correspondencia con un "tipo de nivel", que puede ser SMT, núcleo o "no válido". El espacio de identificación de nivel comienza en 0 y es continuo, lo que significa que si una identificación de nivel no es válida, todas las identificaciones de niveles superiores también lo serán. El tipo de nivel se devuelve en los bits 15:08 de ECX, mientras que el número de procesadores lógicos en el nivel consultado se devuelve en EBX. Finalmente, la conexión entre estos niveles y los identificadores x2APIC se devuelve en EAX[4:0] como el número de bits que el identificador x2APIC debe desplazarse para obtener un identificador único en el siguiente nivel.
Como ejemplo, un procesador Westmere de doble núcleo capaz de hyperthreading (por lo tanto, con dos núcleos y cuatro subprocesos en total) podría tener los identificadores x2APIC 0, 1, 4 y 5 para sus cuatro procesadores lógicos. Hoja Bh (=EAX), subhoja 0 (=ECX) de CPUID podría, por ejemplo, devolver 100h en ECX, lo que significa que el nivel 0 describe la capa SMT (hyperthreading) y devolver 2 en EBX porque hay dos procesadores lógicos (unidades SMT) por núcleo físico. El valor devuelto en EAX para esta subhoja 0 debe ser 1 en este caso, porque desplazar los identificadores x2APIC antes mencionados hacia la derecha un bit proporciona un número central único (en el siguiente nivel de la jerarquía de identificadores de nivel) y borra el identificador de SMT. poco dentro de cada núcleo. Una forma más sencilla de interpretar esta información es que el último bit (número de bit 0) de la identificación x2APIC identifica la unidad SMT/hyperthreading dentro de cada núcleo en nuestro ejemplo. Avanzar a la subleaf 1 (haciendo otra llamada a CPUID con EAX=Bh y ECX=1) podría, por ejemplo, devolver 201h en ECX, lo que significa que este es un nivel de tipo de núcleo, y 4 en EBX porque hay 4 procesadores lógicos en el paquete; EAX devuelto podría ser cualquier valor mayor que 3, porque sucede que el bit número 2 se usa para identificar el núcleo en la identificación x2APIC. Tenga en cuenta que el bit número 1 de la identificación x2APIC no se utiliza en este ejemplo. Sin embargo, EAX devuelto en este nivel bien podría ser 4 (y sucede que es así en un Clarkdale Core i3 5x0) porque eso también proporciona una identificación única en el nivel del paquete (=0 obviamente) al cambiar la identificación de x2APIC en 4 bits. Finalmente, quizás se pregunte qué nos puede decir la hoja EAX=4 que no hayamos descubierto ya. En EAX[31:26] devuelve los bits de máscara APIC reservados para un paquete; eso sería 111b en nuestro ejemplo porque los bits 0 a 2 se usan para identificar procesadores lógicos dentro de este paquete, pero el bit 1 también está reservado aunque no se usa como parte del esquema de identificación del procesador lógico. En otras palabras, los ID de APIC del 0 al 7 están reservados para el paquete, aunque la mitad de estos valores no se asignan a un procesador lógico.
La jerarquía de caché del procesador se explora observando las subhojas de la hoja 4. Los identificadores de APIC también se utilizan en esta jerarquía para transmitir información sobre cómo las unidades y núcleos SMT comparten los diferentes niveles de caché. Para continuar con nuestro ejemplo, la caché L2, que es compartida por unidades SMT del mismo núcleo pero no entre núcleos físicos en Westmere, se indica estableciendo EAX[26:14] en 1, mientras que la información de que la caché L3 se comparte por todo el paquete se indica estableciendo esos bits en (al menos) 111b. Los detalles de la caché, incluido el tipo, el tamaño y la asociatividad de la caché, se comunican a través de los otros registros en la hoja 4.
Tenga en cuenta que las versiones anteriores de la nota de aplicación Intel 485 contienen información engañosa, particularmente con respecto a la identificación y el recuento de núcleos en un procesador multinúcleo; [66] incluso se han incorporado errores por malinterpretar esta información en el código de muestra de Microsoft para usar CPUID, incluso para la edición 2013 de Visual Studio, [67] y también en la página sandpile.org para CPUID, [68] pero Intel El ejemplo de código para identificar la topología del procesador [64] tiene la interpretación correcta y el Manual del desarrollador de software Intel actual tiene un lenguaje más claro. El código de producción multiplataforma (código abierto) [69] de Wildfire Games también implementa la interpretación correcta de la documentación de Intel.
En una presentación de Intel de 2010 se ofrecen ejemplos de detección de topología que involucran procesadores Intel más antiguos (anteriores a 2010) que carecen de x2APIC (por lo tanto, no implementan la hoja EAX=Bh). [70] Tenga en cuenta que el uso de ese método de detección anterior en procesadores Intel 2010 y más nuevos puede sobreestimar la cantidad de núcleos y procesadores lógicos porque el método de detección anterior supone que no hay espacios en el espacio de identificación APIC, y algunos procesadores más nuevos violan esta suposición. (comenzando con la serie Core i3 5x0), pero estos procesadores más nuevos también vienen con un x2APIC, por lo que su topología se puede determinar correctamente utilizando el método de hoja EAX=Bh.
Esto devuelve bits de característica en el registro EAX e información adicional en los registros EBX, ECX y EDX.
IA32_HWP_REQUEST
MSR en las CPU que lo admiten, es necesario configurar el bit 0 del FAST_UNCORE_MSRS_CTL
( 657h
) MSR.Esto devuelve indicadores de funciones extendidas en EBX, ECX y EDX. Devuelve el valor ECX máximo para EAX=7 en EAX.
Esto devuelve indicadores de funciones extendidas en los cuatro registros.
Esto devuelve indicadores de funciones extendidas en EDX.
EAX, EBX y ECX están reservados.
Esta hoja se utiliza para enumerar características y componentes de estado de XSAVE.
La extensión del conjunto de instrucciones XSAVE está diseñada para guardar/restaurar el estado extendido de la CPU (generalmente con el fin de cambiar de contexto ) de una manera que se puede extender para cubrir nuevas extensiones del conjunto de instrucciones sin que el código de cambio de contexto del sistema operativo necesite comprender los detalles del nuevas extensiones. Esto se hace definiendo una serie de componentes de estado , cada uno con un tamaño y desplazamiento dentro de un área de guardado determinada, y cada uno correspondiente a un subconjunto del estado necesario para una extensión de CPU u otra. La EAX=0Dh
hoja CPUID se utiliza para proporcionar información sobre qué componentes de estado admite la CPU y cuáles son sus tamaños/compensaciones, de modo que el sistema operativo pueda reservar la cantidad adecuada de espacio y configurar los bits de habilitación asociados.
Los componentes de estado se pueden subdividir en dos grupos: estado de usuario (elementos de estado que son visibles para la aplicación, por ejemplo, registros vectoriales AVX-512 ) y estado de supervisor (elementos de estado que afectan a la aplicación pero que no son directamente del usuario). visible, por ejemplo, configuración de interrupción en modo usuario). Los elementos de estado de usuario se habilitan configurando sus bits asociados en el XCR0
registro de control, mientras que los elementos de estado de supervisor se habilitan configurando sus bits asociados en IA32_XSS
( 0DA0h
) MSR; los elementos de estado indicados se convierten en los componentes de estado que se pueden guardar. y restaurado con la XSAVE
familia XRSTOR
de instrucciones.
El mecanismo XSAVE puede manejar hasta 63 componentes de estado de esta manera. Los componentes de estado 0 y 1 ( x87 y SSE , respectivamente) tienen compensaciones y tamaños fijos; para los componentes de estado 2 a 62, sus tamaños, compensaciones y algunas banderas adicionales se pueden consultar ejecutando CPUID
con EAX=0Dh
y ECX
estableciendo el índice del estado. -componente. Esto devolverá los siguientes elementos en EAX, EBX y ECX (con EDX reservado):
Intentar consultar un componente de estado no compatible de esta manera da como resultado que EAX, EBX, ECX y EDX se establezcan en 0.
Las subhojas 0 y 1 de CPUID
la hoja 0Dh
se utilizan para proporcionar información sobre las características:
En julio de 2023, los componentes estatales de XSAVE que se han definido arquitectónicamente son:
XCR0
está cableado a 1, de modo que las instrucciones XSAVE siempre admitirán guardar/restaurar el estado x87.XCR0
y IA32_XSS
, el bit 63 está reservado específicamente para la expansión del vector de bits; esto excluye la existencia de un componente de estado 63.Esta hoja proporciona información sobre las capacidades admitidas de la función Intel Software Guard Extensions (SGX). La hoja proporciona múltiples subhojas, seleccionadas con ECX.
La subhoja 0 proporciona información sobre las funciones de hoja SGX admitidas en EAX y los tamaños máximos de enclave SGX admitidos en EDX; ECX está reservado. EBX proporciona un mapa de bits de bits que se pueden configurar en el campo MISCSELECT en SECS (Estructura de control de enclave SGX). Este campo se utiliza para controlar la información escrita en la región MISC de SSA (Área de estado de guardado SGX) cuando un AEX (SGX Se produce una salida asincrónica del enclave).
La subhoja 1 proporciona un mapa de bits de qué bits se pueden configurar en el campo ATRIBUTOS de 128 bits de SECS en EDX:ECX:EBX:EAX (esto se aplica a la copia SECS utilizada como entrada para la ENCLS[ECREATE]
función de hoja). Los 64 bits superiores (proporcionados en EDX:ECX) son un mapa de bits de los cuales se pueden configurar los bits en XFRM (máscara de solicitud de función X); esta máscara es una máscara de bits de los cuales se guardarán los componentes de estado de la CPU (consulte la hoja 0Dh). a la SSA en caso de un AEX; Tiene el mismo diseño que el XCR0
registro de control. Los demás bits se proporcionan en EAX y EBX, de la siguiente manera:
ENCLS[EINIT]
. Este bit debe ser 0 en la copia SECS que se proporciona como entrada a ENCLS[CREATE]
.Las subhojas 2 y superiores se utilizan para proporcionar información sobre qué regiones de memoria física están disponibles para su uso como secciones EPC (Enclave Page Cache) en SGX.
Esta subhoja proporciona información sobre las funciones de Intel Processor Trace (también conocido como seguimiento de instrucciones en tiempo real).
El valor devuelto en EAX es el índice de la subhoja más alta admitida para CPUID con EAX=14h. EBX y ECX proporcionan indicadores de funciones, EDX está reservado.
Esta hoja proporciona información sobre las funciones de AES Key Locker en EAX, EBX y ECX. EDX está reservado.
Esto devuelve una subhoja máxima admitida en EAX y información de funciones AVX10 en EBX. [82] (ECX y EDX están reservados).
El parámetro de llamada más alto se devuelve en EAX.
EBX/ECX/EDX devuelve la cadena de ID del fabricante (igual que EAX=0) en las CPU AMD pero no en las CPU Intel.
Esto devuelve indicadores de funciones extendidas en EDX y ECX.
Muchos de los bits EDX
(bits 0 a 9, 12 a 17, 23 y 24) son duplicados de EDX
la EAX=1
hoja; estos bits están resaltados en amarillo claro. (Estos bits duplicados están presentes en las CPU AMD pero no en las CPU Intel).
Los indicadores de características de AMD son los siguientes: [86] [87]
SYSCALL
/ SYSRET
solo es válido en CPU AuthenticAMD
de la familia 5 modelo 7 ( AMD K6 , 250 nm "Little Foot"); para todos los demás procesadores, se debe usar EDX bit 11 en su lugar.Estas instrucciones se introdujeron por primera vez en el Modelo 7 [88] ; el bit CPUID para indicar su compatibilidad se movió [89] al bit 11 de EDX desde el Modelo 8 ( AMD K6-2 ) en adelante.
SYSCALL
/ SYSRET
solo se establece si la CPUID
instrucción se ejecuta en modo de 64 bits. [90]FCMOV
) compatibleAuthenticAMD
de la familia 6 únicamente; el bit, combinado con la firma del procesador y la velocidad del FSB , se utiliza para identificar procesadores como compatibles con multiprocesador o con la marca Sempron . [95]Estos devuelven la cadena de marca del procesador en EAX, EBX, ECX y EDX. CPUID
debe emitirse con cada parámetro en secuencia para obtener la cadena completa de marca del procesador ASCII de 48 bytes. [98] Es necesario verificar si la característica está presente en la CPU emitiendo CPUID
primero EAX = 80000000h
y verificando si el valor devuelto no es menor que 80000004h
.
En la documentación de Intel/AMD se especifica que la cadena tiene terminación nula , sin embargo, este no es siempre el caso (por ejemplo, se sabe que DM&P Vortex86DX3 y AMD Ryzen 7 6800HS devuelven cadenas de marca no terminadas en nulo en hojas 80000002h
- 80000004h
[99] [100 ] ), y el software no debería depender de él.
#incluye <stdio.h> #incluye <cadena.h> #incluye <cpuid.h> int principal () { regs int sin firmar [ 12 ]; char str [ tamaño de ( regs ) + 1 ]; __cpuid ( 0x80000000 , registros [ 0 ], registros [ 1 ], registros [ 2 ], registros [ 3 ]); si ( regs [ 0 ] < 0x80000004 ) devuelve 1 ; __cpuid ( 0x80000002 , registros [ 0 ], registros [ 1 ], registros [ 2 ], registros [ 3 ]); __cpuid ( 0x80000003 , registros [ 4 ], registros [ 5 ], registros [ 6 ], registros [ 7 ]); __cpuid ( 0x80000004 , registros [ 8 ], registros [ 9 ], registros [ 10 ], registros [ 11 ]); memcpy ( cadena , regs , tamaño de ( regs )); str [ tamaño de ( regs )] = '\0' ; printf ( "%s \n " , cadena ); devolver 0 ; }
Esta función contiene la caché L1 del procesador y las características TLB.
Devuelve detalles de la caché L2 en ECX, incluido el tamaño de línea en bytes (Bits 07 - 00), el tipo de asociatividad (codificada por un campo de 4 bits; Bits 15 - 12) y el tamaño de la caché en KB (Bits 31 - 16). .
#incluir <stdio.h> #incluir <cpuid.h> int principal () { int sin signo eax , ebx , ecx , edx ; unsigned int lsize , assoc , caché ; __cpuid ( 0x80000006 , eax , ebx , ecx , edx ); lsize = ecx & 0xff ; asociación = ( ecx >> 12 ) & 0x07 ; caché = ( ecx >> 16 ) & 0xffff ; printf ( "Tamaño de línea: %d B, tipo de asociación: %d, tamaño de caché: %d KB. \n " , lsize , asociación , caché ); devolver 0 ; }
Esta función proporciona información sobre administración de energía, informes de energía y capacidades RAS ( confiabilidad, disponibilidad y capacidad de servicio ) de la CPU.
AuthenticAMD
de la familia 0Fh Modelo 14h [104] (90 nm Athlon64/Opteron) y está presente en todas las CPU AMD posteriores, excepto aquellas con el indicador 'no_efer_lmsle' configurado.Esta hoja devuelve información sobre las características de AMD SVM ( Secure Virtual Machine ) en EAX, EBX y EDX.
La documentación posterior de AMD, como la #25481 "Especificación de CPUID" rev 2.18 [107] y posteriores, solo enumera el bit como reservado.
En la revisión 2.30 [108] y posteriores, aparece un bit diferente como reservado para uso del hipervisor: CPUID.(EAX=1):ECX[bit 31].
La revisión 2.28 de #25481 enumera el bit como "Ssse3Sse5Dis" [110] ; en la revisión 2.34, aparece como eliminado de la especificación en la revisión 2.32 con el nombre "SseIsa10Compat". [111]
Varios modelos de CPU AMD, para CPUID con EAX=8FFFFFFFh
, devolverán una cadena de huevos de Pascua en EAX, EBX, ECX y EDX. [115] [116] Las cadenas de huevos de Pascua conocidas incluyen:
Devuelve el índice de la hoja de Centauro más alta en EAX. Si el valor devuelto en EAX es menor que C0000001h
, entonces no se admiten las hojas extendidas de Centaur.
Presente en CPU de VIA y Zhaoxin .
En las CPU IDT WinChip ( CentaurHauls
familia 5), las hojas extendidas C0000001h-C0000005h
no codifican ninguna funcionalidad específica de Centaur, sino que son alias de hojas 80000001h-80000005h
. [118]
Esta hoja devuelve información de la función Centaur (principalmente VIA PadLock ) en EDX. [119] [120] (EAX, EBX y ECX están reservados).
CentaurHauls
solo Familia 6 Modelo 9), [121] bits 0,1,4,5 se usan de manera diferente:0x110A
) presenteFEMMS
instrucción (código de operación 0F 0E
) presenteTambién es fácil acceder a esta información desde otros idiomas. Por ejemplo, el código C para gcc a continuación imprime los primeros cinco valores, devueltos por el cpuid:
#incluir <stdio.h> #incluir <cpuid.h> int main () { int sin signo i , eax , ebx , ecx , edx ; for ( i = 0 ; i < 5 ; i ++ ) { __cpuid ( i , eax , ebx , ecx , edx ); printf ( "InfoType %x \n EAX: %x \n EBX: %x \n ECX: %x \n EDX: %x \n " , i , eax , ebx , ecx , edx ); } devolver 0 ; }
En el ensamblado en línea con sabor de los compiladores MSVC y Borland/Embarcadero C (bcc32), la información de destrucción está implícita en las instrucciones:
#incluir <stdio.h> int principal () { int sin signo a , b , c , d , i = 0 ; __asm { /* Haz la llamada. */ mov EAX , i ; CPUID ; /* Guardar resultados. */ mov a , EAX ; mov b , EBX ; mov c , ECX ; mov d , EDX ; } printf ( "InfoType %x \n EAX: %x \n EBX: %x \n ECX: %x \n EDX: %x \n " , i , a , b , c , d ); devolver 0 ; }
Si alguna de las versiones se escribió en lenguaje ensamblador simple, el programador debe guardar manualmente los resultados de EAX, EBX, ECX y EDX en otro lugar si desea seguir usando los valores.
GCC también proporciona un encabezado llamado <cpuid.h>
en sistemas que tienen CPUID. Es __cpuid
una macro que se expande al ensamblaje en línea. El uso típico sería:
#incluir <stdio.h> #incluir <cpuid.h> int principal () { int sin signo eax , ebx , ecx , edx ; __cpuid ( 0 /* cadena de proveedor */ , eax , ebx , ecx , edx ); printf ( "EAX: %x \n EBX: %x \n ECX: %x \n EDX: %x \n " , eax , ebx , ecx , edx ); devolver 0 ; }
Pero si uno solicitara una función extendida que no está presente en esta CPU, no se daría cuenta y podría obtener resultados aleatorios e inesperados. También se proporciona una versión más segura en formato <cpuid.h>
. Comprueba si hay funciones ampliadas y realiza algunas comprobaciones de seguridad más. Los valores de salida no se pasan utilizando parámetros macro similares a referencias, sino punteros más convencionales.
#incluir <stdio.h> #incluir <cpuid.h> int principal () { int sin signo eax , ebx , ecx , edx ; /* 0x81234567 no existe, pero se supone que existe */ if ( ! __get_cpuid ( 0x81234567 , & eax , & ebx , & ecx , & edx )) { printf ( "Advertencia: ¡La solicitud de CPUID 0x81234567 no es válida! \n " ); devolver 1 ; } printf ( "EAX: %x \n EBX: %x \n ECX: %x \n EDX: %x \n " , eax , ebx , ecx , edx ); devolver 0 ; }
Observe los símbolos &a, &b, &c, &d
y la declaración condicional. Si la __get_cpuid
llamada recibe una solicitud correcta, devolverá un valor distinto de cero; si falla, cero. [122]
El compilador de Microsoft Visual C tiene una función incorporada __cpuid()
, por lo que la instrucción cpuid se puede incrustar sin utilizar el ensamblaje en línea, lo cual es útil ya que la versión x86-64 de MSVC no permite el ensamblaje en línea en absoluto. El mismo programa para MSVC sería:
#incluye <stdio.h> #ifdef __MSVC__ #incluye <intrin.h> #endif int principal () { regs int sin firmar [ 4 ]; int yo ; for ( i = 0 ; i < 4 ; i ++ ) { __cpuid ( regs , i ); printf ( "El código %d da %d, %d, %d, %d" , regs [ 0 ], regs [ 1 ], regs [ 2 ], regs [ 3 ]); } devolver 0 ; }
Muchos lenguajes de programación interpretados o compilados son capaces de utilizar CPUID a través de una biblioteca FFI . Una de esas implementaciones muestra el uso del módulo Ruby FFI para ejecutar lenguaje ensamblador que incluye el código de operación CPUID.
.NET 5 y versiones posteriores proporcionan el System.Runtime.Intrinsics.X86.X86base.CpuId
método. Por ejemplo, el siguiente código C# imprime la marca del procesador si admite la instrucción CPUID:
usando System.Runtime.InteropServices ; usando System.Runtime.Intrinsics.X86 ; usando System.Text ; espacio de nombres X86CPUID { clase CPUBrandString { público estático vacío Principal ( cadena [] args ) { if ( ! X86Base . IsSupported ) { Consola . WriteLine ( "Su CPU no admite instrucciones CPUID." ); } else { Span < int > raw = stackalloc int [ 12 ]; ( sin formato [ 0 ], sin formato [ 1 ], sin formato [ 2 ], sin formato [ 3 ]) = X86Base . CpuId ( sin marcar (( int ) 0 x80000002 ), 0 ); ( sin formato [ 4 ], sin formato [ 5 ], sin formato [ 6 ], sin formato [ 7 ]) = X86Base . CpuId ( sin marcar (( int ) 0 x80000003 ), 0 ); ( sin formato [ 8 ], sin formato [ 9 ], sin formato [ 10 ], sin formato [ 11 ]) = X86Base . CpuId ( sin marcar (( int ) 0 x80000004 ), 0 ); Span < byte > bytes = MemoryMarshal . AsBytes ( sin formato ); marca de cadena = Codificación . UTF8 . GetString ( bytes ). Recortar (); Consola . WriteLine ( marca ); } } } }
Algunas de las arquitecturas de CPU que no son x86 también proporcionan ciertas formas de información estructurada sobre las capacidades del procesador, comúnmente como un conjunto de registros especiales:
CPUID
registro de coprocesador que requiere un nivel de excepción EL1 o superior para acceder. [123]STIDP
de 1983 para consultar la ID del procesador. [125]STFLE
) que enumera las funciones de hardware instaladas. [125]PrId
conectados en cadena . [126]PVR
que identifica el modelo de procesador en uso. La instrucción requiere nivel de acceso de supervisor. [127]Las familias de chips tipo DSP y transputadores no han adoptado la instrucción de manera notable, a pesar de tener (en términos relativos) tantas variaciones en el diseño. Podrían existir formas alternativas de identificación del silicio; por ejemplo, los DSP de Texas Instruments contienen un conjunto de registros basado en memoria para cada unidad funcional que comienza con identificadores que determinan el tipo y modelo de la unidad, su revisión de diseño ASIC y las características seleccionadas en la fase de diseño, y continúa con el control y los datos específicos de la unidad. registros. El acceso a estas áreas se realiza simplemente utilizando las instrucciones de carga y almacenamiento existentes; por lo tanto, para tales dispositivos, no hay necesidad de ampliar el conjunto de registros para fines de identificación del dispositivo. [ cita necesaria ]
CPUID
para identificar varias configuraciones del sistemaLas CPU Intel y AMD han reservado el bit 31 de ECX de la hoja CPUID 0x1 como bit presente del hipervisor.
Este bit permite a los hipervisores indicar su presencia al sistema operativo invitado.
Los hipervisores configuran este bit y las CPU físicas (todas las CPU existentes y futuras) configuran este bit en cero.
Los sistemas operativos invitados pueden probar el bit 31 para detectar si se están ejecutando dentro de una máquina virtual.
Bit 31 de ECX de la hoja CPUID 0x1.
Este bit ha sido reservado por Intel y AMD para uso de hipervisores e indica la presencia de un hipervisor.
Las CPU virtuales (hipervisores) establecen este bit en 1 y las CPU físicas (todas las CPU existentes y futuras) establecen este bit en cero.
El software invitado puede sondear este bit para detectar si se están ejecutando dentro de una máquina virtual.
15.2.2 Modo Invitado A este nuevo modo de procesador se ingresa mediante la instrucción VMRUN.
Cuando está en modo invitado, el comportamiento de algunas instrucciones x86 cambia para facilitar la virtualización.
Los números de función CPUID 4000_0000h-4000_00FFh se han reservado para uso del software.
Los hipervisores pueden utilizar estos números de función para proporcionar una interfaz para pasar información del hipervisor al invitado.
Esto es similar a extraer información sobre una CPU física mediante CPUID.
Los hipervisores utilizan el bit CPUID Fn 400000[FF:00] para indicar una plataforma virtual.
El bit de característica CPUID Fn0000_0001_ECX[31] se ha reservado para que lo utilicen los hipervisores para indicar la presencia de un hipervisor.
Los hipervisores establecen este bit en 1 y las CPU físicas lo establecen en cero.
El software invitado puede probar este bit para detectar si se están ejecutando dentro de una máquina virtual.
8FFFFFFFh
. Consultado el 22 de diciembre de 2022.