В архитектуре x86 инструкция CPUID (идентифицируется кодом операции CPUID
) - это дополнительная инструкция процессора (ее название происходит от CPU IDentification), позволяющая программному обеспечению обнаруживать детали процессор. Он был представлен компанией Intel в 1993 году с запуском процессоров Pentium и SL-Enhanced 486.
Программа может использовать CPUID
для определения типа процессора и того, реализованы ли такие функции, как MMX / SSE.
До общей доступности CPUID
, программисты могли бы написать эзотерический машинный код, который использовал бы незначительные различия в поведении ЦП, чтобы определить марку и модель процессора. С появлением процессора 80386 EDX при сбросе указывал версию, но это было доступно для чтения только после сброса, и у приложений не было стандартного способа считывания значения.
Вне семейства x86 от разработчиков в основном все еще требуется использовать эзотерические процессы (включая синхронизацию инструкций или триггеры сбоя ЦП) для определения имеющихся вариаций в конструкции ЦП.
В семействе Motorola 680x0, в котором никогда не было инструкций CPUID какого-либо типа, для определенных инструкций требовались повышенные привилегии. Их можно использовать для различения различных членов семейства ЦП. В Motorola 68010 инструкция MOVE от SR стала привилегированной. Это заметное изменение инструкций (и конечного автомата) позволило 68010 удовлетворить требования к виртуализации Popek и Goldberg. Поскольку 68000 предлагал непривилегированный MOVE от SR, два разных процессора можно было отличить друг от друга по срабатыванию состояния ошибки процессора.
В то время как инструкция CPUID
специфична для архитектуры x86, другие архитектуры (например, ARM) часто предоставляют встроенные регистры, которые можно считывать заданными способами для получения той же информации. инструкцией x86 CPUID.
Код операции CPUID
: 0Fh, A2h(как два байта, или A20Fhкак один слово).
В языке ассемблера инструкция CPUID
не принимает параметров, поскольку CPUID
неявно использует регистр EAX для определения основной категории возвращаемой информации. В более поздней терминологии Intel это называется листом CPUID. CPUID
следует сначала вызвать с EAX = 0
, так как это сохранит в регистре EAX самый высокий параметр вызова EAX (лист), который реализует ЦП.
Для получения информации о расширенных функциях необходимо вызвать CPUID
со старшим битом EAX. Чтобы определить наивысший параметр вызова расширенной функции, вызовите CPUID
с EAX = 80000000h
.
Выходные значения CPUID больше 3, но меньше 80000000 доступны только тогда, когда регистры конкретной модели иметь IA32_MISC_ENABLE.BOOT_NT4 [бит 22] = 0 (что так по умолчанию). Как следует из названия, Windows NT 4.0 до SP6 не загружалась должным образом, если этот бит не был установлен, но более поздние версии Windows не нуждаются в нем, поэтому основные листья больше 4 можно считать видимыми в текущих системах Windows. По состоянию на июль 2014 года основные действительные отпуска продолжаются до 14 часов, но информация, возвращаемая некоторыми листами, не раскрывается в общедоступной документации, т.е. они «зарезервированы».
Некоторые из недавно добавленных листьев также имеют подчиненные листья, которые выбираются через регистр ECX перед вызовом CPUID.
Возвращает строку идентификатора производителя процессора - строку из двенадцати символов ASCII, хранящуюся в EBX, EDX, ECX ( в этой последовательности). Самый высокий базовый параметр вызова (наибольшее значение, которое может быть установлено EAX перед вызовом CPUID
) возвращается в EAX.
Вот список процессоров и самая высокая реализованная функция.
Процессоры | Базовый | Расширенный |
---|---|---|
Ранее Intel 486 | CPUID не реализован | |
Позже Intel 486 и Pentium | 0x01 | Не реализовано |
Pentium Pro, Pentium II и Celeron | 0x02 | Не реализовано |
Pentium III | 0x03 | Не реализовано |
Pentium 4 | 0x02 | 0x8000 0004 |
Xeon | 0x02 | 0x8000 0004 |
Pentium M | 0x02 | 0x8000 0004 |
Pentium 4 с Hyper-Threading | 0x05 | 0x8000 0008 |
Pentium D (8xx) | 0x05 | 0x8000 0008 |
Pentium D (9xx) | 0x06 | 0x8000 0008 |
Core Duo | 0x0A | 0x8000 0008 |
Core 2 Duo | 0x0A | 0x8000 0008 |
Xeon 3000, 5100, 5200, 5300, 5400 серии | 0x0A | 0x8000 0008 |
Core 2 Duo 8000 серии | 0x0D | 0x8000 0008 |
Xeon 5200, серии 5400 | 0x0A | 0x8000 0008 |
Атом | 0x0A | 0x8000 0008 |
Процессоры на базе Nehalem | 0x0B | 0x8000 0008 |
Процессоры на базе IvyBridge | 0x0D | 0x8000 0008 |
Процессоры на базе Skylake (proc base max freq; Автобус реф. freq) | 0x16 | 0x8000 0008 |
Основной лист перечисления атрибутов поставщика системы на кристалле | 0x17 | 0x8000 0008 |
Следующие - известные строки идентификатора производителя процессора:
Далее ng - строки идентификаторов, используемые программными ядрами ЦП с открытым исходным кодом :
Следующие известные строки идентификаторов виртуальных машин:
Например, для процессора GenuineIntel значения, возвращаемые в EBX, равны 0x756e6547, EDX - 0x49656e69, а ECX - 0x6c65746e. Следующий код написан на GNU Assembler для архитектуры x86-64 и отображает строку идентификатора поставщика, а также самый высокий параметр вызова, который реализует ЦП.
.data s0:.asciz "CPUID:% x \ n" s1:.asciz "Максимальный номер реализованной базовой функции:% i \ n" s2:.asciz "Идентификатор поставщика:%.12s \ n".text. align 32.globl main main: pushq% rbp movq% rsp,% rbp subq $ 16,% rsp movl $ 1,% eax cpuid movq $ s0,% rdi movl% eax,% esi xorl% eax,% eax call printf pushq% rbx // -fPIC xorl% eax,% eax cpuid movl% ebx, 0 (% rsp) movl% edx, 4 (% rsp) movl% ecx, 8 (% rsp) popq% rbx // -fPIC movq $ s1,% rdi movl% eax,% esi xorl% eax,% eax call printf movq $ s2,% rdi movq% rsp,% rsi xorl% eax,% eax call printf movq% rbp,% rsp popq% rbp // ret movl $ 1, % eax int $ 0x80
Возвращает степпинг ЦП, модель и информацию о семействе в регистре EAX (также называемую сигнатурой CPU), флаги функций в регистрах EDX и ECX и дополнительная информация о функциях в регистре EBX.
EAX | |||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
Зарезервировано | Идентификатор расширенного семейства | Расширенный ID модели | Зарезервировано | Тип процессора | Идентификатор семейства | Модель | ID шага |
Type | Encoding in Двоичный |
---|---|
Исходный OEM Процессор | 00 |
Процессор Intel Overdrive | 01 |
Двухпроцессорный (не применяется к процессорам Intel486) | 10 |
Зарезервированное значение | 11 |
Биты | EBX | Действительный |
---|---|---|
7: 0 | Индекс бренда | |
15: 8 | Размер строки CLFLUSH (Значение. 8 = размер строки кэша в байтах) | , если установлен флаг функции CLFLUSH. CPUID.01.EDX.CLFSH [бит 19] = 1 |
23:16 | Максимальное количество адресуемых идентификаторов для логических процессоров в этом физическом пакете; Ближайшее целое число степени двойки, которое не меньше этого значения, представляет собой количество уникальных начальных идентификаторов APIC, зарезервированных для адресации различных логических процессоров в физическом пакете. Предыдущее использование: количество логических процессоров на физический процессор; два для процессора Pentium 4 с технологией Hyper-Threading. | , если установлен флаг функции Hyper-threading. CPUID.01.EDX.HTT [бит 28] = 1 |
31:24 | Локальный APIC ID: начальный APIC-ID используется для идентификации исполняющего логического процессора. Его также можно определить по листу cpuid 0BH (CPUID.0Bh.EDX [x2APIC-ID]). | Pentium 4 и последующие процессоры. |
Информация о процессоре и флаги функций зависят от производителя, но обычно значения Intel используются другими производителями для совместимости.
Bit | EDX | ECX | ||
---|---|---|---|---|
Короткое | Функция | Короткое | Функция | |
0 | fpu | Встроенный x87 FPU | sse3 | Prescott New Instructions -SSE3 (PNI) |
1 | vme | Расширения режима Virtual 8086 (например, VIF, VIP, PIV) | pclmulqdq | PCLMULQDQ |
2 | de | Расширения отладки (CR4 бит 3) | dtes64 | 64-битное хранилище отладки (edx бит 21) |
3 | pse | Расширение размера страницы | monitor | инструкции MONITOR и MWAIT (SSE3 ) |
4 | tsc | Time Stamp Counter | ds-cpl | Хранилище отладки, отвечающее требованиям CPL |
5 | msr | Регистры, зависящие от модели | vmx | Расширения виртуальной машины |
6 | pae | Расширение физического адреса | smx | Расширения безопасного режима (LaGrande ) |
7 | mce | Исключение проверки компьютера | est | Enhanced SpeedStep |
8 | cx8 | CMPXCHG8 (сравнение и замена ) инструкция | tm2 | Thermal Monitor 2 |
9 | apic | Onboard Advanced Programmable Контроллер прерываний | ssse3 | Дополнительные инструкции SSE3 |
10 | (reserved) | cnxt-id | L1 Context ID | |
11 | sep | Инструкции SYSENTER и SYSEXIT | sdbg | Silicon Debug interface |
12 | mtrr | Диапазон типов памяти Регистры | fma | Объединенное умножение-сложение (FMA3) |
13 | pge | Страница Глобальный бит разрешения в CR4 | cx16 | CMPXCHG16B инструкция |
14 | mca | Архитектура машинной проверки | xtpr | Может отключить отправку сообщений о приоритете задачи |
15 | cmov | Условное перемещение и FCMOV инструкции | pdcm | Возможности Perfmon и отладки |
16 | pat | Атрибут страницы Таблица | (зарезервирована) | |
17 | pse-36 | 36-битное расширение размера страницы | pcid | Идентификаторы контекста процесса (CR4 бит 17) |
18 | psn | Серийный номер процессора | dca | Прямой доступ к кэшу для записи DMA |
19 | clfsh | инструкция CLFLUSH (SSE2 ) | sse4.1 | SSE4.1 инструкции |
20 | (зарезервировано) | sse4.2 | SSE4.2 инструкции | |
21 | ds | Отладочное хранилище: сохранение трассировки выполненных переходов | x2apic | x2APIC |
22 | acpi | MSR встроенного терморегулятора для ACPI | movbe | инструкция MOVBE (big-endian ) |
23 | mmx | MMX инструкции | popcnt | POPCNT инструкция |
24 | fxsr | FXSAVE, инструкции FXRESTOR, CR4 бит 9 | tsc-deadline | APIC реализует однократную операцию, используя значение крайнего срока TSC |
25 | sse | инструкции SSE (также известные как Новые инструкции Katmai) | aes | Набор инструкций AES |
26 | sse2 | SSE2 instructions | xsave | XSAVE, XRESTOR, XSETBV, XGETBV |
27 | ss | Кэш ЦП реализует само- snoop | osxsave | XSAVE, разрешенный ОС |
28 | htt | Hyper-threading | avx | Advanced Vector Extensions |
29 | tm | Тепловизор автоматически ограничивает температуру | f16c | F16C (половинная точность ) Функция FP |
30 | ia64 | IA64 процессор, эмулирующий x86 | rdrnd | RDRAND (встроенный генератор случайных чисел) функция |
31 | pbe | Возможность пробуждения Pending Break Enable (вывод PBE #) | гипервизор | гипервизор присутствует (всегда ноль на физических ЦП) |
Зарезервированные поля должны быть замаскированы перед использованием их в целях идентификации процессора.
Возвращает список дескрипторов, указывающих возможности кеширования и TLB в регистрах EAX, EBX, ECX и EDX.
Возвращает серийный номер процессора. Серийный номер процессора был введен в Intel Pentium III, но из-за соображений конфиденциальности эта функция больше не реализована в более поздних моделях (бит функции PSN всегда сброшен). Процессоры Transmeta Efficeon и Crusoe также предоставляют эту функцию. Однако процессоры AMD не поддерживают эту функцию ни в каких моделях процессоров.
Для процессоров Intel Pentium III серийный номер возвращается в регистрах EDX: ECX. Для процессоров Transmeta Efficeon он возвращается в регистрах EBX: EAX. А для процессоров Transmeta Crusoe он возвращается только в регистре EBX.
Обратите внимание, что для работы функция серийного номера процессора должна быть включена в настройках BIOS.
Эти два листа используются для топологии процессора (поток, ядро, пакет) и перечисления иерархии кэша в многопользовательской системе Intel. ядерные (и гиперпоточные) процессоры. Начиная с 2013 года AMD не использует эти листья, но имеет альтернативные способы выполнения перечисления ядер.
В отличие от большинства других оконечных значений CPUID, лист Bh будет возвращать разные значения в EDX в зависимости от того, на каком логическом процессоре выполняется инструкция CPUID; значение, возвращаемое в EDX, фактически является идентификатором x2APIC логического процессора. Однако пространство идентификаторов x2APIC не отображается постоянно на логические процессоры; в сопоставлении могут быть пробелы, что означает, что некоторые промежуточные идентификаторы x2APIC не обязательно соответствуют какому-либо логическому процессору. Дополнительная информация для сопоставления идентификаторов x2APIC с ядрами предоставляется в других регистрах. Хотя лист Bh имеет подчиненные листы (выбираемые ECX, как описано ниже), на значение, возвращаемое в EDX, влияет только логический процессор, на котором выполняется инструкция, но не подчиненный лист.
Топология процессора (ов), представленная листом Bh, является иерархической, но с той странной оговоркой, что порядок (логических) уровней в этой иерархии не обязательно соответствует порядку в физической иерархии (SMT / ядро / пакет). Однако каждый логический уровень может быть запрошен как подуровень ECX (листа Bh) на предмет его соответствия «типу уровня», который может быть SMT, основным или «недопустимым». Пространство идентификаторов уровня начинается с 0 и является непрерывным, что означает, что если идентификатор уровня недопустим, все идентификаторы более высокого уровня также будут недопустимыми. Тип уровня возвращается в битах 15:08 ECX, а количество логических процессоров на запрошенном уровне возвращается в EBX. Наконец, связь между этими уровнями и идентификаторами x2APIC возвращается в EAX [4: 0] как количество битов, на которое должен быть сдвинут идентификатор x2APIC, чтобы получить уникальный идентификатор на следующем уровне.
В качестве примера, двухъядерный процессор Westmere, поддерживающий гиперпоточность (таким образом, имея два ядра и четыре потока всего), может иметь x2APIC id 0, 1, 4 и 5 для четырех логических процессоров. Leaf Bh (= EAX), subbleaf 0 (= ECX) CPUID может, например, возвращать 100h в ECX, что означает, что уровень 0 описывает уровень SMT (гиперпоточность), и возвращает 2 в EBX, потому что есть два логических процессора (блоки SMT) на физическое ядро. В этом случае значение, возвращаемое в EAX для этого 0-подуровня, должно быть равно 1, потому что сдвиг вышеупомянутых идентификаторов x2APIC вправо на один бит дает уникальный номер ядра (на следующем уровне иерархии идентификаторов уровней) и стирает идентификатор SMT. бит внутри каждого ядра. Более простой способ интерпретировать эту информацию заключается в том, что последний бит (бит номер 0) идентификатора x2APIC идентифицирует модуль SMT / Hyper-Threading внутри каждого ядра в нашем примере. Переход к subbleaf 1 (путем еще одного вызова CPUID с EAX = Bh и ECX = 1) может, например, вернуть 201h в ECX, что означает, что это уровень типа ядра, и 4 в EBX, потому что в нем 4 логических процессора пакет; Возвращаемый EAX может иметь любое значение больше 3, потому что так случается, что бит номер 2 используется для идентификации ядра в идентификаторе x2APIC. Обратите внимание, что бит номер 1 идентификатора x2APIC не используется в этом примере. Однако EAX, возвращаемый на этом уровне, вполне может быть равен 4 (и так бывает на Clarkdale Core i3 5x0), потому что это также дает уникальный идентификатор на уровне пакета (= 0, очевидно) при смещении идентификатора x2APIC на 4 бита. Наконец, вы можете задаться вопросом, что может сказать нам лист EAX = 4, чего мы еще не выяснили. В EAX [31:26] он возвращает биты маски APIC, зарезервированные для пакета; в нашем примере это будет 111b, потому что биты от 0 до 2 используются для идентификации логических процессоров внутри этого пакета, но бит 1 также зарезервирован, хотя и не используется как часть схемы идентификации логического процессора. Другими словами, идентификаторы APIC от 0 до 7 зарезервированы для пакета, даже если половина этих значений не отображается на логический процессор.
Иерархия кеша процессора исследуется путем просмотра подчиненных листов листа 4. Идентификаторы APIC также используются в этой иерархии для передачи информации о том, как различные уровни кеша совместно используются модулями SMT. и сердечники. Чтобы продолжить наш пример, кэш L2, который совместно используется модулями SMT одного и того же ядра, но не между физическими ядрами на Westmere, обозначается EAX [26:14], установленным в 1, в то время как информация о том, что кэш L3 является общим для всего пакета указывается установкой этих битов в (как минимум) 111b. Детали кэша, включая тип, размер и ассоциативность кэша, передаются через другие регистры на листе 4.
Помните, что более старые версии примечания 485 приложения Intel содержат некоторую вводящую в заблуждение информацию, особенно в отношении идентификации и подсчета ядра в многоядерном процессоре; ошибки из-за неправильной интерпретации этой информации были даже включены в пример кода Microsoft для использования cpuid, даже для выпуска Visual Studio 2013 года, а также на странице sandpile.org для CPUID, но образец кода Intel для определения топологии процессора имеет правильный интерпретация, а текущее Руководство разработчика программного обеспечения Intel имеет более четкий язык. Кросс-платформенный производственный код (с открытым исходным кодом) от Wildfire Games также реализует правильную интерпретацию документации Intel.
Примеры обнаружения топологии с участием более старых (до 2010 г.) процессоров Intel, в которых отсутствует x2APIC (таким образом, не реализуется лист EAX = Bh), приведены в презентации Intel 2010 г. Помните, что использование этого старого метода обнаружения на процессорах Intel 2010 и более новых может привести к завышению количества ядер и логических процессоров, поскольку старый метод обнаружения предполагает отсутствие пробелов в пространстве идентификаторов APIC, и это предположение нарушается некоторыми новыми процессорами (начиная с серии Core i3 5x0), но эти новые процессоры также поставляются с x2APIC, поэтому их топологию можно правильно определить с помощью листового метода EAX = Bh.
Возвращает флаги расширенных функций в EBX, ECX и EDX.
Bit | EBX | ECX | EDX | |||
---|---|---|---|---|---|---|
Short | Feature | Краткое | Функция | Короткая | Функция | |
0 | fsgsbase | Доступ к базе% fs и% gs | prefetchwt1 | Инструкция PREFETCHWT1 | (зарезервировано) | |
1 | IA32_TSC_ADJUST | avx512_vbmi | AVX-512 Инструкции по обработке векторных битов | (зарезервировано) | ||
2 | sgx | Software Guard Extensions | umip | Предотвращение инструкций пользовательского режима | avx512_4vnniw | AVX-512 4-регистровые инструкции нейронной сети |
3 | bmi1 | Набор команд обработки битов 1 | pku | Ключи защиты памяти для страниц пользовательского режима | avx512_4fmaps | AVX-512 4-регистровое умножение с накоплением Одинарная точность |
4 | hle | TSX Hardware Lock Elision | ospke | PKU, разрешенная ОС | fsrm | Fast Short REP MOVSB |
5 | avx2 | Advanced Vector Extensions 2 | waitpkg | Временная пауза и мониторинг на уровне пользователя / wait | (зарезервировано) | |
6 | FDP_EXCPTN_ONLY | avx512_vbmi2 | AVX-512 Инструкции по обработке векторных битов 2 | |||
7 | smep | Предотвращение выполнения режима супервизора | cet_ss | Теневой стек принудительного управления потоком (CET) | ||
8 | bmi2 | Набор команд обработки битов 2 | gfni | Инструкции поля Галуа | avx512_vp2intersect | AVX-512 VP2INTERSECT Инструкции по двойному и четверному слову |
9 | erms | Enhanced REP MOVSB / STOSB | vaes | Вектор Набор команд AES ( VEX-256 / EVEX) | SRBDS_CTRL | Меры по предотвращению выборки данных из буфера специальных регистров |
10 | invpcid | Инструкция INVPCID | vpclmulqdq | Набор инструкций CLMUL (VEX-256 / EVEX) | md_clear | Инструкция VERW очищает буферы ЦП |
11 | rtm | TSX Ограниченная транзакционная память | avx512_vnni | AVX-512 Инструкции векторной нейронной сети | (зарезервировано) | |
12 | pqm | Платф orm Quality of Service Monitoring | avx512_bitalg | AVX-512 Инструкции BITALG | ||
13 | FPU CS и FPU DS устарели | (зарезервировано) | tsx_force_abort | |||
14 | mpx | Intel MPX (Расширения защиты памяти) | avx512_vpopcntdq | Счетчик популяции векторов AVX-512 Двойное и четырехсловное | SERIALIZE | Выполнение инструкции сериализации |
15 | pqe | Обеспечение качества обслуживания платформы | (зарезервировано) | Гибрид | ||
16 | avx512_f | AVX-512 Foundation | 5-уровневая подкачка | TSXLDTRK | Отслеживание адреса приостановки загрузки TSX | |
17 | avx512_dq | AVX-512 Инструкции по двойному и четверному слову | mawau | Значение настройки ширины адреса MPX пользовательского пространства, используемой BNDLDX и BNDSTX Intel MPX инструкции в 64-битном режиме | (зарезервировано) | |
18 | rdseed | RDSEED instruction | pconfig | Конфигурация платформы (шифрование памяти Te chnologies, инструкции) | ||
19 | adx | Intel ADX (Multi-Precision Add-Carry Instruction Extensions) | lbr | Архитектурные записи последней ветви | ||
20 | smap | Предотвращение доступа в режиме супервизора | cet_ibt | Непрямое отслеживание переходов принудительного управления потоком (CET) | ||
21 | avx512_ifma | AVX-512 Инструкции умножения-сложения с объединением целых чисел | (зарезервировано) | |||
22 | pcommit | Инструкция PCOMMIT | rdpid | Чтение идентификатора процессора и IA32_TSC_AUX | amx-bf16 | Вычисление плитки по номерам bfloat16 |
23 | clflushopt | инструкция CLFLUSHOPT | (зарезервировано) | (зарезервировано) | ||
24 | clwb | инструкция CLWB | (зарезервировано) | amx -tile | Архитектура плитки | |
25 | intel_pt | Intel Processor Trace | cldemote | Понижение уровня строки кэша | amx-int8 | Вычисление мозаики для 8-битных целых чисел |
26 | avx512_pf | AVX-512 Инструкции предварительной выборки | (зарезервированы) | IBRS_IBPB / spec_ctrl | Управление спекуляциями, часть Indirect Branch Control (IBC):. Indirect Спекуляция с ограничением ветвлений (IBRS) и. Барьер косвенного прогнозирования ветвлений (IBPB) | |
27 | avx512_er | AVX-512 Экспоненциальные и взаимные инструкции | MOVDIRI | stibp | Однопоточный предсказатель косвенного перехода, часть IBC | |
28 | avx512_cd | AVX-512 Инструкции по обнаружению конфликтов | MOVDIR64B | L1D_FLUSH | IA32_FLUSH_CMD MSR | |
29 | sha | Расширения Intel SHA | ENQCMD | Хранение в очереди | IA32_ARCH_CAPABILITIES | >Спекулятивное смягчение последствий побочного канала|
30 | avx512_bw | AVX-512 Инструкции по байтам и словам | sgx_lc | Конфигурация запуска SGX | IA32_CORE_CAPABILITIES | Поддержка возможностей ядра, зависящих от модели, в MSR |
31 | avx512_vl | AVX-512 Длина вектора Расширения | pks | Ключи защиты для страниц режима супервизора | ssbd | Отключение спекулятивного обхода хранилища, как смягчение последствий для спекулятивного обхода хранилища (IA32_SPEC_CTRL) |
Возвращает флаги расширенных функций в EAX.
.
Bit | EAX | |
---|---|---|
Short | Feature | |
0 | (зарезервировано) | |
1 | (зарезервировано) | |
2 | (зарезервировано) | |
3 | (зарезервировано) | |
4 | (зарезервировано) | |
5 | avx512_bf16 | AVX-512 BFLOAT16 инструкции |
6 | (зарезервировано) | |
7 | (зарезервировано) | |
8 | (зарезервировано) | |
9 | (зарезервировано) | |
10 | (зарезервировано) | |
11 | (зарезервировано) | |
12 | (зарезервировано) | |
13 | (зарезервировано) | |
14 | (зарезервировано) | |
15 | (зарезервировано) | |
16 | (зарезервировано) | |
17 | (зарезервировано) | |
18 | (зарезервировано) | |
19 | (зарезервировано) | |
20 | (зарезервировано) | |
21 | (зарезервировано) | |
22 | (зарезервировано) | |
23 | (зарезервировано) | |
24 | (зарезервировано) | |
25 | (зарезервировано) | |
26 | (зарезервировано) | |
27 | (зарезервировано) | |
28 | (зарезервировано) | |
29 | (зарезервировано) | |
30 | (зарезервировано) | |
31 | (зарезервировано) |
Самый высокий параметр вызова ter возвращается в EAX.
Возвращает флаги расширенных функций в EDX и ECX.
Флаги функций AMD :
Bit | EDX | ECX | ||
---|---|---|---|---|
Short | Функция | Короткая | Функция | |
0 | fpu | Встроенная x87 FPU | lahf_lm | LAHF / SAHF в длинном режиме |
1 | vme | Расширения виртуального режима (VIF) | cmp_legacy | Hyperthreading недействительно |
2 | de | Расширения отладки (CR4 бит 3) | svm | Secure Virtual Machine |
3 | pse | Расширение размера страницы | extapic | Extended APIC space |
4 | tsc | Счетчик отметок времени | cr8_legacy | CR8 в 32-битном режиме |
5 | msr | Зависящие от модели регистры | abm | Расширенная обработка битов (lzcnt и popcnt ) |
6 | pae | Расширение физического адреса | sse4a | SSE4a |
7 | mce | Исключение проверки компьютера | misalignsse | Несовпадение SSE режим |
8 | cx8 | CMPXCHG8 (сравнение и замена ) инструкция | 3dnowprefetch | PREFETCH и PREFETCHW инструкции ons |
9 | apic | Встроенный Расширенный программируемый контроллер прерываний | osvw | Видимое обходное решение ОС |
10 | (зарезервировано) | ibs | Выборка на основе инструкций | |
11 | syscall | Инструкции SYSCALL и SYSRET | xop | Набор инструкций XOP |
12 | mtrr | Регистры диапазона типов памяти | skinit | Инструкции SKINIT / STGI |
13 | pge | Бит глобального разрешения страницы в CR4 | wdt | Сторожевой таймер |
14 | mca | Архитектура машинной проверки | (зарезервировано) | |
15 | cmov | Условно move и FCMOV instructions | lwp | Легкое профилирование |
16 | pat | Таблица атрибутов страницы | fma4 | 4 operands fused multiply-add |
17 | pse36 | 36-bit page size extension | tce | Translation Cache Extension |
18 | ( reserved) | |||
19 | mp | Multiprocessor Capable | nodeid_msr | NodeID MSR |
20 | nx | NX bit | (reserved) | |
21 | (reserved) | tbm | Trailing Bit Manipulation | |
22 | mmxext | Extended MMX | topoext | Topology Extensions |
23 | mmx | MMX instructions | perfctr_core | Core performance counter extensions |
24 | fxsr | FXSAVE, FXRSTOR instructions, CR4 bit 9 | perfctr_nb | NB performance counter extensions |
25 | fxsr_opt | FXSAVE/FXRSTOR optimizations | (reserved) | |
26 | pdpe1gb | Gibibyte pages | dbx | Data breakpoint extensions |
27 | rdtscp | RDTSCP instruction | perftsc | Performance TSC |
28 | (reserved) | pcx_l2i | L2I perf counter extensions | |
29 | lm | Long mode | (reserved) | |
30 | 3dnowext | Extended 3DNow! | (reserved) | |
31 | 3dnow | 3DNow! | (reserved) |
These return the processor brand string in EAX, EBX, ECX and EDX. CPUID
must be issued with each parameter in sequence to get the entire 48-byte null-terminated ASCII processor brand string. It is necessary to check whether the feature is present in the CPU by issuing CPUID
with EAX = 80000000h
first and checking if the returned value is greater or equal to 80000004h.
#include// GCC-provided #include #include int main(void) { uint32_t brand[12]; if (!__get_cpuid_max(0x80000004, NULL)) { fprintf(stderr, "Feature not implemented."); return 2; } __get_cpuid(0x80000002, brand+0x0, brand+0x1, brand+0x2, brand+0x3); __get_cpuid(0x80000003, brand+0x4, brand+0x5, brand+0x6, brand+0x7); __get_cpuid(0x80000004, brand+0x8, brand+0x9, brand+0xa, brand+0xb); printf("Brand: %s\n", brand); }
This function contains the processor’s L1 cache and TLB characteristics.
Returns details of the L2 cache in ECX, including the line size in bytes (Bits 07 - 00), type of associativity (encoded by a 4 bits field; Bits 15 - 12) and the cache size in KiB (Bits 31 - 16).
#include// GCC-provided #include #include int main(void) { uint32_t eax, ebx, ecx, edx; if (__get_cpuid(0x80000006, eax, ebx, ecx, edx)) { printf("Line size: %d B, Assoc. Type: %d; Cache Size: %d KB.\n", ecx 0xff, (ecx>>12) 0x07, (ecx>>16) 0xffff); возврат 0; } else { fputs(stderr, "CPU does not support 0x80000006"); return 2; } }
This function provides advanced power management feature identifiers. EDX bit 8 indicates support for invariant TSC.
Returns largest virtual and physical address sizes in EAX.
It could be used by the hypervisor in a virtual machine system to report physical/virtual address sizes possible with the virtual CPU.
EBX is used for features:
ECX provides core count.
EDX provides information specific to RDPRU (the maximum register identifier allowed) in 31-16. The current number as of Zen 2 is 1 for MPERF and APERF.
Специально для процессоров AMD K7 и K8, это возвращает строку «IT'S HAMMER TIME» в EAX, EBX, ECX и EDX.
Эту информацию легко получить и на других языках. Например, приведенный ниже код C для gcc выводит первые пять значений, возвращаемых идентификатором cpuid:
#include/ * Это работает в 32- и 64-разрядных системах. См. [[Встроенный ассемблер # В реальных компиляторах]] за советами по чтению этого кода. * / int main () {/ * Четыре регистра не нужно инициализировать, так как процессор будет писать поверх них. * / int инфо-тип, a, b, c, d; для (инфо-тип = 0; инфо-тип < 5; infotype ++) { __asm__("cpuid" : "=a" (a), "=b" (b), "=c" (c), "=d" (d) // The output variables. EAX ->a и наоборот: «0» (инфо-тип)); // Поместите инфо-тип в EAX. printf ("Инфо-тип% x \ nEAX:% x \ nEBX:% x \ nECX:% x \ nEDX:% x \ n", инфо-тип, a, b, c, d); } return 0; }
В компиляторах MSVC и Borland / Embarcadero C (bcc32) встроенная ассемблерная информация неявно содержится в инструкциях:
#includeint main () {unsigned int InfoType = 0; беззнаковые int a, b, c, d; __asm {/ * Сделай звонок. * / mov EAX, InfoType; cpuid; / * Сохраняем результаты. * / mov a, EAX; mov b, EBX; mov c, ECX; mov d, EDX; } printf ("InfoType% x \ nEAX:% x \ nEBX:% x \ nECX:% x \ nEDX:% x \ n", InfoType, a, b, c, d); возврат 0; }
Если какая-либо из версий была написана на простом языке ассемблера, программист должен вручную сохранить результаты EAX, EBX, ECX и EDX в другом месте, если он хочет продолжать использовать значения.
GCC также предоставляет заголовок с именем
в системах с CPUID. __cpuid
- это макрос, расширяющийся до встроенной сборки. Типичное использование:
#include#include int main (void) {int a, b, c, d; __cpuid (0 / * строка поставщика * /, a, b, c, d); printf ("EAX:% x \ nEBX:% x \ nECX:% x \ nEDX:% x \ n", a, b, c, d); возврат 0; }
Но если кто-то запросит расширенную функцию, отсутствующую на этом процессоре, он не заметит этого и может получить случайные, неожиданные результаты. Более безопасная версия также представлена в
. Он проверяет наличие расширенных функций и выполняет еще несколько проверок безопасности. Выходные значения передаются не с использованием параметров макроса, подобных ссылкам, а с использованием более обычных указателей.
#include#include int main (void) {int a, b, c, d; if (! __ get_cpuid (0x81234567 / * не существует, но предполагается, что он существует * /, a, b, c, d)) {fprintf (stderr, "Предупреждение: запрос CPUID 0x81234567 недействителен! \ n"); } printf ("EAX:% x \ nEBX:% x \ nECX:% x \ nEDX:% x \ n", a, b, c, d); возврат 0; }
Обратите внимание на амперсанды в a, b, c, d
и условном операторе. Если вызов __get_cpuid
получает правильный запрос, он вернет ненулевое значение, в случае сбоя - ноль.
Компилятор Microsoft Visual C имеет встроенную функцию __cpuid ()
, поэтому инструкция cpuid может быть встроена без использования встроенной сборки, что удобно, поскольку версия MSVC для x86-64 вообще не допускает встроенную сборку. Та же программа для MSVC будет выглядеть так:
#include#include int main () {int cpuInfo [4]; for (int a = 0; a < 5; a++) { __cpuid(cpuInfo, a); std::cout << "The code " << a << " gives " << cpuInfo[0] << ", " << cpuInfo[1] << ", " << cpuInfo[2] << ", " << cpuInfo[3] << '\n'; } return 0; }
Многие интерпретируемые или скомпилированные языки сценариев могут использовать CPUID через библиотеку FFI. Одна такая реализация показывает использование модуля Ruby FFI для выполнять язык ассемблера, который включает код операции CPUID.
Некоторые архитектуры ЦП, отличные от x86, также предоставляют определенные формы структурированной информации о возможностях процессора, обычно в виде набор специальных регистров:
CPUID
, для доступа к которому требуется EL1 или выше.STIDP
) с 1983 IBM 4381 для запроса идентификатора процессора.STFLE
), в котором перечислены установленные аппаратные функции.PrId
) и ряд последовательно соединенных регистров конфигурации.PVR
), идентифицирующий используемую модель процессора. Для инструкции требуется уровень доступа супервизора. Семейства микросхем, подобныхDSP и транспьютер, не воспринимают инструкцию каким-либо заметным образом, несмотря на то, что (в относительном выражении) имеется такое же количество вариаций в дизайн. Могут присутствовать альтернативные способы идентификации кремния; например, DSP от Texas Instruments содержат набор регистров на основе памяти для каждого функционального блока, который начинается с идентификаторов, определяющих тип и модель блока, его конструктивную версию ASIC и функции, выбранные в этап проектирования и продолжается с регистрами управления и данных для конкретных устройств. Доступ к этим областям осуществляется простым использованием существующих инструкций загрузки и сохранения; таким образом, для таких устройств нет необходимости расширять набор регистров для целей идентификации устройства.
CPUID
для определения различных системных настроек