Система команд x86 |
|
Программирование - Архитектура и система команд микропроцессоров x86 |
CPUID
Влияние команды на флаги и форматы команды:
0F A2 |
CPUID |
Идентификация CPU |
Pentium |
cpuid |
Описание:
Команда CPUID впервые была введена в процессоре Pentium, она предназначена для считывания программным обеспечением информации о продавце, семействе, модели и поколении процессора, а также специфической для процессора дополнительной информации (поддерживаемые наборы команд, размеры буферов, кэшей, разнообразные расширения архитектуры и т.п.).
Перед выполнением команды CPUID в регистр EAX должно помещаться входное значение, которое и указывает — какую информацию необходимо выдать. Для разных моделей процессоров задокументированы различные наборы допустимых входных значений в регистре EAX перед выполнением команды CPUID. В общем случае их можно разделить на стандартные (поддерживаемые всеми производителями) и расширенные (так или иначе отличающиеся для процессоров разных моделей и производителей).
Стандартные функции
Входное значение EAX = 0
При входном значении EAX = 0, после выполнения команды CPUID регистр EAX будет содержать максимальное значение, понимаемое командой CPUID (при запросе стандартных функций), а в регистрах EBX, EDX и ECX будет находится строка идентификации производителя процессора (EBX содержит первых 4 символа, EDX содержит следующие 4 символа и ECX содержит последние 4 символа). В таблице 6.33. приведены значения, выдаваемые наиболее распространенными моделями микропроцессоров.
Таблица 6.33. Строки идентификации, возвращаемые процессорами различных производителей
Содержимое регистров после выполнения команды CPUID (EAX = 0) |
||
Тип процессора (производитель) |
EAX |
EBX : EDX : ECX |
486SL … Pentium III Xeon (Intel) |
x |
GenuineIntel (0x756E6547h : 0x49656E69h : 0x6C65746Eh) |
Pentium 4, Pentium 4D, Pentium 4E, Xeon, Core i3, i5, i7, Core 2 Duo (Intel) |
x |
GenuineIntel |
Atom, Celeron, Celeron M (Intel) |
x |
GenuineIntel |
6x86, 6x86L (Cyrix) |
1 (01h) |
CyrixInstead (0x69727943h : 0x736E4978h : 0x64616574h) |
6x86MX (Cyrix) |
1 (01h) |
CyrixInstead |
MediaGX (Cyrix) |
1 (01h) |
CyrixInstead |
MediaGX MMX Enhansed (Cyrix) |
2 (02h) |
CyrixInstead |
WinChip 2, 2A, 2B, C6 (IDT) |
1 (01h) |
CentaurHauls (0x746E6543h : 0x48727561h :0x736C7561h) |
VIA Eden, Eden-N, Eden ESP, Eden ULV, Cyrix III, C3, C3-M, C7, C7-M, C7-D, CoreFusion (VIA) |
1 (01h) |
CentaurHauls |
VIA nano, nano-M, nano X2, Eden X2, QuadCore (VIA) |
10 (0Ah) |
CentaurHauls |
VIA Eden X4 (VIA) |
13 (0Dh) |
CentaurHauls |
Am486, Am5x86, AMD K5, AMD K6, AMD K6-2, AMD K6-2+, AMD K6-III, AMD K6-III+, AMD K-7, AMD Athlon, AMD Athlon XP, Duron, AMD Athlon 64, DualCore AMD Athlon 64 X2, AMD Opteron, 2x AMD Opteron, DualCore AMD Opteron, AMD Sempron, AMD K-8, AMD Turion, DualCore AMD Turion (AMD) |
1 (01h) |
AuthenticAMD (0x68747541h : 0x444D4163h : 0x69746E65h) |
2x DualCore AMD Opteron, QuadCore AMD Phenom, DualCore AMD Phenom II X2, TripleCore AMD Phenom II X3, QuadCore AMD Phenom II X4, QuadCore AMD Phenom II TWKR, AMD Propus, AMD Athlon II X4, DualCore AMD Athlon II X2, AMD Sempron, 2x HexaCore AMD Opteron, 2x DodecaCore AMD Opteron (AMD) |
5 (05h) |
AuthenticAMD |
HexaCore AMD Phenom II X6, Mobile DualCore AMD E2, QuadCore AMD A8, DualCore AMD Bobcat, DualCore AMD C-50, DualCore AMD G-T56N, DualCore AMD E-xxx (AMD) |
6 (06h) |
AuthenticAMD |
QuadCore AMD Bulldozer, QuadCore AMD FX, OctalCore AMD FX, HexaCore AMD FX, 2x 16-Core AMD Opteron, QuadCore AMD A10, QuadCore AMD A8, QuadCore AMD A12, DualCore AMD A9, QuadCore AMD A4, QuadCore AMD Athlon, QuadCore AMD Temash, DualCore AMD GX, QuadCore AMD A6, Summit Ridge A stepping, OctalCore AMD Ryzen 7, QuadCore AMD Ryzen 5, 12-Core AMD Ryzen, 16-Core AMD Ryzen, 32-Core AMD EPYC (AMD) |
13 (0Dh) |
AuthenticAMD |
RDC IAD 100 (RDC Semiconductor) |
1 (01h) |
(0x756E6547h : 0x20656E69h : 0x43445220h) |
SiS550 (SiS) |
1 (01h) |
SiS SiS SiS (0x20536953h : 0x20536953h : 0x20536953h) |
Nx586 (NexGen) |
1 (01h) |
NexGenDriven (0x4778654Eh : 0x72446E65h : 0x6E657669h) |
Transmeta Crusoe, Transmeta Efficeon (Transmeta) |
3 (03h) |
GenuineTMx86 (0x756E6547h : 0x54656E69h : 0x3638784Dh) |
Rise mP6, Rise mP6-II (Rise) |
1 (01h) |
RiseRiseRise (0x65736952h : 0x65736952h : 0x65736952h) |
(UMC) |
|
UMC UMC UMC (0x20434D55h : 0x20434D55h : 0x20434D55h) |
Geode GX1, GXLV, GXm (National Semiconductor) |
2 (02h) |
Geode by NSC (0x646F6547h : 0x79622065h : 0x43534E20h) |
Geode GX2 (National Semiconductor) |
1 (01h) |
Geode by NSC |
Vortex86 (DM&P Electronics) |
1 (01h) |
Vortex86 SoC (0x74726F56h : 0x36387865h : 0x436F5320h) |
Входное значение EAX = 1
После выполнения команды CPUID со входным значением 1, регистр EAX будет содержать следующую информацию (т.н. сигнатура процессора):
- EAX[3:0] — (Stepping) номер разработки микропроцессора;
- EAX[7:4] — (Model) модель микропроцессора;
- EAX[11:8] — (Family) номер семейства микропроцессора;
- EAX[13:12] — (Type) тип микропроцессора (00b – стандартный, 01b – OverDrive, 10b – Dual), процессоры Pentium OverDrive processor for Pentium ошибочно возвращают 00b в поле тип;
- EAX[15:14] — зарезирвировано;
- EAX[19:16] — (Extended Model) расширенная информация о модели микропроцессора*;
- EAX[27:20] — (Extended Family) расширенная информация о семействе микропроцессора**;
- EAX[31:28] — зарезирвировано.
* Полная информация о модели микропроцессора, начиная с процессоров Intel Celeron (Model 16), перестала помещаться в поле EAX[7:4], и появилось новое поле EAX[19:16], которое ранее было зарезервированным. Теперь модель должна формироваться композицией полей Model и Extended Model (со сдвигом влево на 4 бита):
M = EAX[19:16] << 4 + EAX[7:4]
** Для поддержки будущих поколений процессоров, начиная с процессоров Intel Celeron (Model 16), информация о семействе микропроцессора размещается не только в поле EAX[11:8], но появилось новое поле EAX[27:20], которое ранее было зарезервированным. Теперь информация о семействе должна формироваться как сумма полей Family и Extended Family:
F = EAX[27:20] + EAX[11:8]
Регистры EBX и ECX зарезервированы.
В регистре EDX будет содержаться информация о некоторых свойствах и возможностях микропроцессора. Установленный флаг свойств указывает на то, что соответствующее свойство (возможность, функция) данной моделью микропроцессора поддерживается. Информация о свойствах определена следующим образом:
- EDX[0] — (FPU) наличие интегрированного FPU, поддерживающего систему команд Intel387;
- EDX[1] — (VME) поддержка механизма виртуальных прерываний, битов CR4.VME, CR4.PVI и флагов EFLAGS.VIF, EFLAGS.VIP и расширенного TSS;
- EDX[2] — (DE) поддержка расширений отладки (точки останова для ввода/вывода) и бита CR4.DE.
- EXD[3] — (PSE) поддержка расширений размеров страниц (страницы 4Мб), бита CR4.PSE и бита PS в элементах каталога страниц;
- EDX[4] — (TSC) поддержка команды RDTSC и бита CR4.TSD;
- EDX[5] — (MSR) поддержка команд RDMSR и WRMSR;
- EDX[6] — (PAE) поддержка расширений физического адреса (более 4Гб — точный размер зависит от модели процессора): расширенного формата элементов таблиц страниц, страниц размером 2Мб, таблицы указателей на каталог страниц, бита CR4.PAE;
- EDX[7] — (MCE) поддержка прерывания 18 (Контроль машины) и бита CR4.MCE;
- EDX[8] — (CXS) поддержка команды CMPXCHG8B;
- EDX[9] — (APIC) наличие APIC (Advanced Programmable Interrupt Controller), контроллер должен быть включен и готов к работе, в процессоре AMD-K-5 бит 9 используется для индикации поддержки глобальных страниц вместо бита 13, который зарезервирован, индикации APIC контроллера в этом процессоре нет;
- EDX[10] — зарезервировано;
- EDX[11] — (SEP) поддержка команд ускоренного системного доступа SYSENTER и SYSEXIT, процессор Pentium Pro (Model 1) возвращает 1 в бите SEP, однако команды ускоренного системного доступа в нем не могут использоваться.
- EDX[12] — (MTRR) поддержка регистров MTRRs (Memory Type Range Registers), они относятся к MSR-регистрам;
- EDX[13] — (PGE) поддержка глобальных страниц, бита CR4.PGE, бита PG в элементах таблиц страничных преобразований;
- EDX[14] — (MCA) поддержка регистра MCG_CAP (Machine check global capability) (относится к MSR-регистрам);
- EDX[15] — (CMOV) поддержка команды CMOV и при наличии интегрированного FPU (EDX[0]=1) – команд FCMOV и FCOMI;
- EDX[16] — (PAT) поддержка таблицы атрибутов страниц (Page Attribute Table) (дополнительный механизм, управления кэшированием);
- EDX[17] — (PSE-36) поддержка расширения физического адреса (PSE-36) для 4Мб страниц;
- EDX[18] — поддержка уникального 96-разрядного серийного номера;
- EDX[22:19] — зарезервировано;
- EDX[23] — (MMX) поддержка команд MMX;
- EDX[24] — (FXSR) поддержка бита CR4.OSFXSR и команд быстрого сохранения/восстановления состояния FPU/MMX/SIMD (FXSAVE, FXRSTOR);
- EDX[25] — (SIMD) поддержка расширений потоковой обработки SIMD;
- EDX[31:26] — зарезервировано.
Не все из указанных битов свойств определены в различных моделях процессоров различных производителей. В ранних моделях некоторые из этих битов указываются как зарезервированные, некоторые биты могут по разному интерпретироваться. Но, поскольку постоянно выпускаются модифицированные версии старых моделей процессоров, могут встречаться самые разнообразные комбинации (основные наиболее важные для прикладного программирования биты, такие как: наличие интегрированного FPU, поддержка команд MMX и т.п., везде интерпретируются одинаково).
В таблице 6.34. представлена информация о содержимом регистров некоторых наиболее распространенных моделей микропроцессоров после выполнения команды CPUID с входным EAX = 1.
Таблица 6.34
Таблица 6.34.1. Процессоры поколений 1...5
Тип процессора |
EAX[27:20] Extended Family |
EAX[19:16] Extended Model |
EAX[11:8] Family |
EAX[7:4] Model |
EAX[3:0] Stepping |
EDX |
Intel486DX2 OverDrive |
0 |
0 |
4 |
3 |
x |
н/д |
Intel486SL |
0 |
0 |
4 |
4 |
x |
н/д |
Intel486SX2 |
0 |
0 |
4 |
5 |
x |
н/д |
Intel Write-Back Enhanced 486DX2 |
0 |
0 |
4 |
7 |
x |
н/д |
Intel486DX4 |
0 |
0 |
4 |
8 |
x |
н/д |
Intel486DX4 OverDrive |
0 |
0 |
4 |
8 |
x |
н/д |
Pentium (60, 66) |
0 |
0 |
5 |
1 |
x |
н/д |
Pentium (75…200) |
0 |
0 |
5 |
2 |
x |
н/д |
Pentium OverDrive processor for Pentium (60, 66) |
0 |
0 |
5 |
1 |
x |
н/д |
Pentium OverDrive processor for Pentium (75...133) |
0 |
0 |
5 |
2 |
x |
н/д |
Pentium OverDrive processor for Intel486 |
0 |
0 |
5 |
3 |
x |
н/д |
Pentium MMX (166, 200) |
0 |
0 |
5 |
4 |
x |
н/д |
6x86(L) (Cyrix) |
x |
x |
5 |
2 |
x |
0x00000105h |
6x86MX (Cyrix) |
x |
x |
6 |
0 |
x |
0x0080A13Dh |
MediaGX (Cyrix) |
x |
x |
4 |
4 |
x |
0x00000001h |
MediaGX MMX Enhanсed (Cyrix) |
x |
x |
5 |
4 |
x |
0x00808131h |
WinChip 2 (IDT) |
x |
x |
5 |
8 |
x |
0x008000B5h |
Am486 (AMD) |
x |
x |
4 |
x |
x |
0x00000001h |
Am5x86 (AMD) |
x |
x |
4 |
x |
x |
0x00000001h |
AMD-K5 (Model 0) (AMD) |
x |
x |
5 |
0 |
x |
0x000003BFh |
AMD-K5 (Model 1) (AMD) |
x |
x |
5 |
1 |
x |
0x000021BFh |
AMD-K5 (Model 2) (AMD) |
x |
x |
5 |
2 |
x |
0x000021BFh |
AMD-K5 (Model 3) (AMD) |
x |
x |
5 |
3 |
x |
0x000021BFh |
Rise MP6 (Rise) |
x |
0 |
5 |
0 |
4 |
н/д |
н/д — не документировано. Производители выпускали и выпускают |
||||||
многие процессоры с различной функциональностью (в разных |
||||||
корпусах, по разным технологиям и т.п.). Соответственно, в |
||||||
процессорах одного наименования и производителя одни и те же |
||||||
функции могут и поддерживаться и не поддерживаться. |
Таблица 6.34.2. Процессоры микроархитектуры Intel P6
Тип процессора |
EAX[27:20] Extended Family |
EAX[19:16] Extended Model |
EAX[11:8] Family |
EAX[7:4] Model |
EAX[3:0] Stepping |
Процессоры Pentium Pro с ядром версии B0 (0,35...0,6 мкм):
|
0 |
0 |
6 |
1 |
1 |
Процессоры Pentium Pro с ядром версии C0 (0,35...0,6 мкм):
|
0 |
0 |
6 |
1 |
2 |
Процессоры Pentium Pro с ядром версии sA0 (0,35...0,6 мкм):
|
0 |
0 |
6 |
1 |
6 |
Процессоры Pentium Pro с ядром версии sA1 (0,35...0,6 мкм):
|
0 |
0 |
6 |
1 |
7 |
Процессоры Pentium Pro с ядром версии sB1 (0,35...0,6 мкм):
|
0 |
0 |
6 |
1 |
9 |
Процессоры с ядром типа Klamath версии C0 (0,35 мкм):
|
0 |
0 |
6 |
3 |
3 |
Процессоры с ядром типа Klamath версии C1 (0,35 мкм):
|
0 |
0 |
6 |
3 |
4 |
Процессоры с ядром типа Deschutes версии dA0 (0,25 мкм):
|
0 |
0 |
6 |
5 |
0 |
Процессоры с ядром типа Deschutes версии dA1 (0,25 мкм):
|
0 |
0 |
6 |
5 |
1 |
Процессоры с ядром типа Deschutes версии dB0 (0,25 мкм):
|
0 |
0 |
6 |
5 |
2 |
Процессоры с ядром типа Deschutes версии dB1 (0,25 мкм):
|
0 |
0 |
6 |
5 |
3 |
Процессоры с ядром типа P6T (модифицированное Deschutes) версии TdB0 (0,25 мкм):
|
0 |
0 |
6 |
3 |
2 |
Процессоры с ядром типа Mendocino версии A0 (0,25 мкм):
|
0 |
0 |
6 |
6 |
0 |
Процессоры с ядром типа Mendocino версии B0 (0,25 мкм):
|
0 |
0 |
6 |
6 |
5 |
Процессоры с ядром типа Dixon версии mdbA0 (0,25 мкм):
|
0 |
0 |
6 |
6 |
10 |
Процессоры с ядром типа Katmai версии kB0 (0,25 мкм):
|
0 |
0 |
6 |
7 |
2 |
Процессоры с ядром типа Katmai версии kC0 (0,25 мкм):
|
0 |
0 |
6 |
7 |
3 |
Процессоры с ядром типа Coppermine версии cA2 (0,18 мкм):
|
0 |
0 |
6 |
8 |
1 |
Процессоры с ядром типа Coppermine версии cB0 (0,18 мкм):
|
0 |
0 |
6 |
8 |
3 |
Процессоры с ядром типа Coppermine версии cC0 (0,18 мкм):
|
0 |
0 |
6 |
8 |
6 |
Процессоры с ядром типа Coppermine версии cD0 (0,18 мкм):
|
0 |
0 |
6 |
8 |
10 |
Процессоры с ядром типа Cascades-2M версии A0 (0,18 мкм):
|
0 |
0 |
6 |
10 |
0 |
Процессоры с ядром типа Cascades-2M версии A1 (0,18 мкм):
|
0 |
0 |
6 |
10 |
1 |
Процессоры с ядром типа Cascades-2M версии B0 (0,18 мкм):
|
0 |
0 |
6 |
10 |
4 |
Процессоры с ядром типа Tualatin-256 версии tA0 (0,13 мкм):
|
0 |
0 |
6 |
11 |
0 |
Процессоры с ядром типа Tualatin-256 версии tA1 (0,13 мкм):
|
0 |
0 |
6 |
11 |
1 |
Процессоры с ядром типа Tualatin-256 версии tB1 (0,13 мкм):
|
0 |
0 |
6 |
11 |
4 |
1 — Тип микропроцессора EAX[13:12] = 01b (OverDrive). |
|||||
2 — Ядро Covington представляет из себя ядро Deschutes без КЭШ памяти второго уровня (L2 cache). Соответственно и процессоры на этом ядре отличают от процессоров Deschutes и Tonga по результатам команды CPUID со входным значением EAX = 2, которая возвращает подробные данные о КЭШ памяти. |
|||||
3 — Процессоры Mobile Pentium II на ядре Tonga можно отличить от процессоров Pentium II на ядре Deschutes по отсутвию у первых встроенного APIC-контроллера (определяется по значению бита EDX[9] после выполнения CPUID со входным значением EAX = 1). |
|||||
4 — Процессоры Pentium II Xeon на ядре Drake можно отличить от процессоров Pentium II на ядре Deschutes по наличию у первых поддержки расширения физического адреса PSE-36 (определяется по значению бита EDX[17] после выполнения CPUID со входным значением EAX = 1. |
|||||
5 — Процессоры Mobile Pentium II на ядре Dixon можно отличить от процессоров Mobile Celeron и модулей на их основе (Mobile Celeron Module) на ядре Mendocino, анализируя размер КЭШ памяти второго уровня (L2 cache), что определяется по результатам команды CPUID со входным значением EAX = 2, которая возвращает подробные данные о КЭШ памяти. Mobile Pentium II на ядре Dixon имеет размер L2-КЭШ равный 256 кБ (42h), а процессор Mobile Celeron — 128 кБ (41h). |
|||||
6 — Процессоры Pentium III Xeon на ядре Tanner иногда можно отличить от процессоров Pentium III на ядре Katmai, анализируя размер КЭШ памяти второго уровня (L2 cache), что определяется по результатам команды CPUID со входным значением EAX = 2, которая возвращает подробные данные о КЭШ памяти. Pentium III Xeon может иметь размер L2-КЭШ равным 512 кБ, 1 МБ или 2 МБ, а процессор Pentium III — только 512 кБ. То есть для таких процессоров при размере КЭШ памяти 512 кБ Intel вообще не предоставляет какого-то штатного средства, позволяющего их различать. Для устранения описанной неоднозначности в последующие модели процессоров был введен дополнительный возвращаемый параметр Brand ID (см. 6) |
|||||
7 — Различать модификации процессоров по данным о типах и размерах используемой в них КЭШ памяти оказалось достаточно неудобно. Данный метод не всегда позволяет получить корректиный результат. Чтобы расширить возможности идентификации в процессорах Intel, начиная с Pentium III (Coppermine, 0,18 мкм) был введен дополнительный возвращаемый параметр Brand ID, который определяется по значению битов EBX[7:0] после выполнения команды CPUID со входным значением EAX = 1. Во всех более ранних моделях процессоров эти биты считались зарезервированными и в них возвращались всегда нули. |
Таблица 6.34.3. Процессоры микроархитектуры P6+ (Intel Pentium M/Enhanced Pentium M)
Тип процессора |
EAX[27:20] Extended Family |
EAX[19:16] Extended Model |
EAX[11:8] Family |
EAX[7:4] Model |
EAX[3:0] Stepping |
Процессоры с ядром типа Banias-512 версии B1 (0,13 мкм):
|
0 |
0 |
6 |
9 |
5 |
Процессоры с ядром типа Tolapai версии B0 (65 нм):
|
0 |
1 |
6 |
5 |
0 |
Процессоры с ядром типа Dothan версии A2 (90 нм):
|
0 |
0 |
6 |
13 |
2 |
Процессоры с ядром типа Dothan версий B0/B1 (90 нм):
|
0 |
0 |
6 |
13 |
6 |
Процессоры с ядром типа Dothan версий C0/C1 (90 нм):
|
0 |
0 |
6 |
13 |
8 |
Процессоры с ядром типа Yonah (65 нм):
2 |
0 |
0 |
6 |
14 |
1 |
Процессоры с ядром типа Yonah (65 нм):
2 |
0 |
0 |
6 |
14 |
4 |
Процессоры с ядром типа Yonah версии C0 (65 нм):
2, 3 |
0 |
0 |
6 |
14 |
8 |
Процессоры с ядром типа Yonah версии D0 (65 нм):
2, 3 |
0 |
0 |
6 |
14 |
12 |
1 — Параметр Brand ID определяется по значению битов EBX[7:0] после выполнения команды CPUID со входным значением EAX = 1. |
|||||
2 — Процессоры на ядре типа Yonah имеют одно (Yonah-SC или Yonah-1P) или два (Yonah-DC или Yonax-2P) процессорных ядра. |
|||||
3 — Все модели процессоров Core Duo и Core Solo на ядре Yonah имеют КЭШ память второго уровня (L2 cache) объемом 2 Мб, а у двухядерных Pentium Dual-Core Mobile объем КЭШа составляет 1 Мб. Соответственно и процессоры эти можно отличить друг от друга по результатам команды CPUID со входным значением EAX = 2, которая возвращает подробные данные о КЭШ памяти. |
|||||
4 — Процессоры Xeon на ядре Sossaman имеют КЭШ память второго уровня (L2 cache) объемом 2 Мб и два процессорных ядра, а у процессоров Embedded Celeron на этом же ядре объем КЭШа составляет 1 Мб и имеется только одно процессорное ядро. Соответственно и процессоры эти можно отличить друг от друга по результатам команды CPUID со входным значением EAX = 2, которая возвращает подробные данные о КЭШ памяти. Кроме того, все процессоры на ядре Sossaman можно отличить от процессоров на ядре Yonah по наличию у первых поддержки расширения физического адреса PAE (определяется по значению бита EDX[6] после выполнения CPUID со входным значением EAX = 1. |
Входное значение EAX = 2
Команда CPUID со входным значением EAX = 2 предназначена для получения информации об объеме и типе КЭШ памяти микропроцессора. После выполнения этой команды в регистрах EAX, EBX, EDX, ECX содержится соответствующая информация, причем, в младших 8-ми битах регистра EAX (регистр AL) содержится число, указывающее на то, сколько раз подряд необходимо выполнить команду CPUID со входным EAX = 2, чтобы получить достоверную информацию о микропроцессоре (в случае AL = 1, команда должна выполняться однократно).
Самый старший бит в каждом 32-битном регистре указывает на то, содержит ли данный регистр информацию (бит 31 = 0) или зарезирвирован (бит 31 = 1). Все байты незарезирвированных регистров (EAX, EBX, EDX, ECX) содержат т.н. дескрипторы, которые описывают всю, имеющуюся в микропроцессоре КЭШ память. Значения этих дескрипторов расшифровываются по таблице 6.35.
Таблица 6.35. Рашифровка значений дескрипторов, возвращаемых командой CPUID в регистрах EAX, EBX, EDX, ECX
Значение дескриптора |
Описание |
00h |
Нуль-дескриптор (без значения) |
01h |
TLB команд, 4К страницы: 4-направленный ассоциативный, 32 элемента |
02h |
TLB команд, 4М страницы: полностью ассоциативный, 2 элемента |
03h |
TLB данных, 4К страницы: 4-направленный ассоциативный, 64 элемента |
04h |
TLB данных, 4М страницы: 4-направленный ассоциативный, 8 элементов |
06h |
КЭШ команд: размер 8К,4-направленный ассоциативный, длина строки 32 байта |
0Ah |
КЭШ данных: размер 8К,2-направленный ассоциативный, длина строки 32 байта |
0Ch |
КЭШ данных: размер 16К,4-направленный ассоциативный, длина строки 32 байта |
40h |
Нет интегрированного КЭШа второго уровня (L2 cache) |
41h |
Объединенный КЭШ: размер 128К, 4-направленный ассоциативный, длина строки 32 байта |
42h |
Объединенный КЭШ: размер 256К, 4-направленный ассоциативный, длина строки 32 байта |
43h |
Объединенный КЭШ: размер 512К, 4-направленный ассоциативный, длина строки 32 байта |
44h |
Объединенный КЭШ: размер 1М, 4-направленный ассоциативный, длина строки 32 байта |
45h |
Объединенный КЭШ: размер 2М, 4-направленный ассоциативный, длина строки 32 байта |
Например, процессор Pentium Pro с КЭШ второго уровня 256К возвращает следующие значения в регистрах: EAX = 0x03020101h, EBX = 0x00000000h, ECX = 0x00000000h, EDX = 0x06040A42h; а процессор Pentium II (Model 3) с КЭШ второго уровня 512К — EAX = 0x03020101h, EBX = 0x00000000h, ECX = 0x00000000h, EDX = 0x0C040843h.
Входное значение EAX = 3
Команда CPUID со входным значением EAX = 3 — одно из последних нововведений Intel. Она предназначена для чтения т.н. идентификационного номера микропроцессора — уникального 96-разрядного номера, который может использоваться программным обеспечением, например, для авторизации доступа к каким-либо ресурсам, идентификации пользователя и т.п. После выполнения этой команды регистр ECX содержит младшие 32 бита идентификационного номера, а регистр EDX — средние 32 бита. Старшие 32 бита идентификационного номера — это данные, выдаваемые в регистре EAX командой CPUID с входным EDX = 1. Стандартная форма записи идентификационного номера, определяемая фирмой Intel, выглядит следующим образом: XXXX-XXXX-XXXX-XXXX-XXXX-XXXX (где X – шестнадцатиричная цифра, запись в верхнем регистре).
Входное значение EAX > 3
Все функции с входным значением в EAX большим, чем 3, но меньшим, чем выдаваемое функцией с EAX = 0 предельное значение, относятся к специфическим функциям модели, в типовой технической документации не описаны и могут меняться от процессора к процессору.
Нестандартные функции
Для некоторых процессоров-клонов (AMD, Cyrix, IDT…) определены т.н. нестандартные (расширенные) функции команды CPUID. Они вызываются при входных значениях в EAX больших 0x7FFFFFFFh. Полное описание этих функций вы сможете найти в технических руководствах фирм-производителей по конкретным процессорам. Здесь приводятся лишь некоторые наиболее важные.
Входное значение EAX = 0x80000000h
Функция может быть вызвана только после идентификации производителя процессора. После ее выполнения в регистре EAX будет содержаться максимальное входное значение EAX для поддерживаемых расширенных (нестандартных) функций. В таблице даны результаты выполнения данной команды на некоторых процессорах.
Таблица 6.36. Содержимое регистров после выполнения команды CPUID с EAX = 0x80000000h
Тип процессора |
EAX |
MediaGX MMX Enhansed (Cyrix) |
0x800000005h |
WinChip 2 (IDT) |
0x800000005h |
Am486 (AMD) |
0x800000000h |
Am5x86 (AMD) |
0x800000000h |
AMD-K5 (Model 0) (AMD) |
0x800000000h |
AMD-K5 (Model 1) (AMD) |
0x800000005h |
AMD-K5 (Model 2) (AMD) |
0x800000005h |
AMD-K5 (Model 3) (AMD) |
0x800000005h |
AMD-K6 (AMD) |
0x800000005h |
AMD-K6-2 (AMD) |
0x800000005h |
AMD-K6-3 (AMD) |
0x800000005h |
Входное значение EAX = 0x80000001h
Результат выполнения данной команды практически идентичен команде CPUID с входным значением EAX = 1. Разница заключается в том, что в этом случае в регистре EDX содержится т.н. расширенная информация о свойствах (Extended Feature Flags). Помимо стандартной информации, здесь содержатся данные о наличии у процессора самых разнообразных специальных возможностей, которые не являются стандартными для процессоров Intel (например, поддержка команд 3DNow!).
У микропроцессоров разных производителей расширенная информация о свойствах, выдаваемая в регистре EDX после выполнения CPUID c входным EAX = 0x80000001h, определяется по разному. Для точной идентификации всех выдаваемых значений обратитесь к фирменной документации на конкретный тип микропроцессора. Для прикладного программирования имеет значение только один бит — бит, показывающий наличие поддержки 3DNow! команд. Согласно установленному фирмой AMD стандарту этот бит помещается в EDX[31] (0 – 3DNow! не поддерживается, 1 – 3DNow! поддерживается).
Входное значение EAX = 0x80000002h, 0x80000003h, 0x80000004h
Команда CPUID с указанными входными значениями в EAX выдает последовательно в регистрах EAX, EBX, ECX, EDX 48-ми значную ASCII строку, содержащую полное наименование процессора. Эта строка обычно используется BIOS для вывода на экран ПК при начальной загрузке.
Входное значение EAX = 0x80000005h
Данная команда предназначена для получения информации о TLB и КЭШе процессора (выдается в регистрах EBX, ECX, EDX).
Операция:
switch (EAX)
case 0: (* EAX = 0 *)
EAX = hv; (* hv = 2 для процессора Pentium II *)
(* hv - это максимально возможное входное значение, которое распознается командой CPUID *)
EBX = Строка идентификации продавца;
EDX = Строка идентификации продавца;
ECX = Строка идентификации продавца;
break;
case 1: (* EAX = 1 *)
EAX[3:0] = Номер поколения;
EAX[7:4] = Модель;
EAX[11:8] = Семейство;
EAX[13:12] = Тип;
EAX[31:14] = Зарезервировано;
EBX = Зарезервирован; (* 0 *)
ECX = Зарезервирован; (* 0 *)
EDX = Флаги особенностей;
break;
case 2: (* EAX = 2 *)
EAX = Данные о КЭШ и TLB;
EBX = Данные о КЭШ и TLB;
ECX = Данные о КЭШ и TLB;
EDX = Данные о КЭШ и TLB;
break;
case 3: (* EAX = 3 *)
ECX = младшие 32 бита идентификационного номера CPU;
EDX = средние 32 бита идентификационного номера CPU;
break;
default: (* EAX > hv *)
EAX = Зарезервирован; (* Неопределен *)
EBX = Зарезервирован; (* Неопределен *)
ECX = Зарезервирован; (* Неопределен *)
EDX = Зарезервирован; (* Неопределен *)
break;
end-of-switch
Особые ситуации защищенного режима:
Нет.
Особые ситуации режима реальной адресации:
Нет.
Особые ситуации режима V86:
Нет.
Замечание:
До появления процессора Pentium для программного обеспечения существовала определенная проблема в определении того, под управлением какого процессора и с какими возможностями идет выполнение программы. В зависимости же от модели процессора разработчикам программного обеспечения хотелось использовать разные алгоритмы вычислений, "заточенные" именно на характеристики и поддерживаемые команды конкретного процессора.
Например, следующим образом можно отличить процессоры 8086/88 от Intel286 и более поздних:
pushf ; запись в стек значения регистра FLAGS
pop AX ; загрузка в регистр AX значения FLAGSиз стека
mov CX, AX ; сохраняем исходное значение FLAGS
and AX, 0fffh ; очистка битов 12-15 в регистре FLAGS
push AX ; запись в стек нового значения FLAGS
popf ; загрузка из стека измененного значения в регистр FLAGS
pushf ; повторное сохранение в стек значения регистра FLAGS
pop AX ; загрузка нового значения FLAGS в регистр AX
and AX, 0f000h ; если биты 12-15 нового значения установлены, то
cmp AX, 0f000h ; процессор типа 8086/8088 или 80186/88
je cpu_8086 ; переход, если процессор 8086/8088 или 80186/88
... ; дальнейшее уточнение типа процессора
Для отличия процессоров 8086/88 от Intel286 и более поздних используется также и другой алгоритм, который основан на ошибке, присутствовавшей в микрокоде процессоров 8086/88 и 80186/88. Эти процессоры при выполнении команды PUSH SP сперва уменьшали на 2 указатель стека, а уже потом сохраняли его значение в стеке. В более поздних моделях процессоров эта ошибка была устранена. Пример идентификации, основанный на этом свойстве приведен ниже:
push SP ; сохраняем указатель стека
pop AX ; считываем сохраненное значение в регистр AX
cmp AX, SP ; сравниваем значение, взятое из стека, со значением SP
jne cpu_8086 ; переход, если процессор 8086/8088 или 80186/88
... ; дальнейшее уточнение типа процессора
Предложенный алгоритм, однако, не позволяет различать процессоры 8086/88 и 80186/88. Чтобы идентифицировать процессоры 80186/88 можно использовать особенности исполнения команд циклического сдвига. Эти команды в качестве входного операнда используют значение в регистре CL. Для ускорения вычислений в процессорах, начиная с 80186/88 старшие разряды этого операнда маскируются так, что значащими являются только младшие 5 разрядов. То есть самым большим допустимым значением для числа сдвигов является значение 31. В процессорах 8086/8088 такого ограничения нет. Алгоритм идентификации, основанный на описанном свойстве, выглядит следующим образом.
mov AX, 0ffffh ; помещаем в регистр AX исходное значение для сдвига
mov CL, 32 ; используем 32 как заданное число требуемых сдвигов
shl AX, CL ; проверяем, равен ли результат сдвига нулю
jz cpu_8086 ; переход, если процессор 8086/8088
... ; дальнейшее уточнение типа процессора
Для идентификации различных процессоров-клонов из семейств 8086/88 и 80186/88 существуют различные дополнительные методики, основанные на специфике исполнения этими процессорами некоторых команд (см., например, замечания к командам MUL, AAD, AAM). Чтобы идентифицировать процессоры Intel286 и старше можно использовать следующий код.
...; процессор Intel386 или старше
pushfd
pop eax
mov edx, eax
xor eax, 00240000h ; flip bits 18 (AC) and 21 (ID)
push eax
popfd
pushfd
pop eax
xor eax, edx ; check if both bits didn't toggle
jz _is_80386
shr eax, 19 ; check if only bit 18 toggled
jz _is_80486_without_CPUID
На практике самым надежным способом определения типа процессора программным обеспечением, начиная с процессора Intel186, является выполнение специфических команд с целью генерации особой ситуации Неопределенный код операции (#UD) и выявление таким образом характерных поддерживаемых и неподдерживаемых команд с последующей идентификацией модели процессора по матрице соответствия. Тем не менее, по прошествии многих лет старые методологии ушли в прошлое и основным способом идентификации стала именно команда CPUID.
Для того, чтобы узнать — поддерживается ли команда CPUID конкретной моделью процессора, программное обеспечение должно проверить флаг 21 (ID) регистра EFLAGS. Если в программе можно установить и сбросить этот флаг, значит команда CPUID данным процессором поддерживается. В противном случае, выполнение данной команды может вызвать особую ситуацию #UD (Неопределенный код операции). Ниже приведен пример программы, определяющей поддержку команды CPUID.
pushfd ; EFLAGS копировать в стек
pop eax ; выбрать в EAX содержимое стека
mov ebx, eax ; сохранить выбранное значение флагов
xor eax, 200000h ; изменить бит 21 в выбранном значении флагов
push eax ; поместить новое значение флагов в стек
popfd ; выбрать в EFLAGS из стека новые значения флагов
pushfd ; EFLAGS копировать в стек
pop eax ; выбрать в EAX содержимое стека
xor eax, ebx ; сравнить считанное новое значение флагов с сохраненным ранее
je no_cpuid ; переход, eсли бит 21 не изменился
Следующим обязательным шагом должна быть команда CPUID со входным значением EAX = 0, позволяющая определить — какие входные значения поддерживает данный процессор. Помимо этого, интерпретация битов поддерживаемых свойств в регистре EDX (при входном значении EAX = 1) должна производиться только после анализа информации о производителе и модели микропроцессора, так как существуют некоторые отличия как по количеству, так и по назначению некоторых битов в разных моделях процессоров.
Использование информации, выдаваемой командой CPUID с входным EAX = 1 в прикладных задачах необходимо, например, для определения поддержки команд MMX. Это может быть сделано следующим образом.
mov eax,1 ; установка входного значения EAX=1
CPUID ; выполнение функции
test edx, 800000 ; проверка 23-го бита
jnz YES_MM ; переход, если MMX поддерживается
Аналогично, но с использованием расширенной функции CPUID, определяется поддержка 3DNow! команд в процессорах AMD (K6) и IDT (WinChip 2).
...
[проверка поддержки CPUID]
[проверка поддержки расширенных
функций – CPUID (EAX = 80000000h)]
...
mov eax,80000001h ; установка входного значения EAX=8000_0001h
CPUID ; выполнение расширенной функции
test edx,80000000h ; проверка 31-го бита
jnz YES_3DNow! ; переход, если 3DNow! поддерживается
Значения выдаваемые командой CPUID очень важны для правильного программирования систем. Попытка использования неподдерживаемых конкретным микропроцессором свойств и команд может привести к самым разнообразным исключительным ситуациям и во многих случаях реакция микропроцессора вообще не предсказуема.
Во многих микропроцессорах некоторые свойства и функции могут быть программно отключены путем программирования специальных регистров модели (MSR), которые для каждого микропроцессора различны (см. технические описания для каждой конкретной модели). В этом случае результат действия стандартных функций команды CPUID также изменяется — процессор индицирует поддержку только включенных функций. Более того, в некоторых процессорах можно программно отключить поддержку самой команды CPUID. Тогда, при попытке ее выполнения, будет генерироваться особая ситуация #UD (Неопределенный код операции).
Все права защищены © Алексей Ровдо, 1994-2023. Перепечатка возможна только по согласованию с владельцем авторских прав. admin@club155.ru