Blog. Just Blog

Как на Ассемблере получить строку названия процессора

Версия для печати Добавить в Избранное Отправить на E-Mail | Категория: Образ мышления: Assembler | Автор: ManHunter
Для получения различной информации о процессоре используется ассемблерная команда CPUID. С ее помощью можно, например, узнать марку процессора и набор поддерживаемых им функций. На старых процессорах инструкция CPUID отсутствовала, поэтому во всех руководствах рекомендуют сперва проверить, что процессор ее поддерживает. Конечно, сейчас придется немало напрячься, чтобы найти такие древние компьютеры для ваших приложений, но порядок есть порядок. Итак, чтобы удостоверится, что команда CPUID доступна, достаточно попытаться изменить 21-й бит расширенного регистра EFLAGS. Если бит успешно поменяется, то инструкция CPUID процессором поддерживается, если регистр флагов остался без изменений, то процессор команду CPUID не поддерживает.
  1.         ; Проверить, поддерживается ли команда CPUID
  2.         pushfd
  3.         pop     eax
  4.         ; Получить регистр флагов
  5.         mov     ebx,eax
  6.         ; Изменить 21-й бит в регистре флагов
  7.         xor     eax, 200000h
  8.         ; Сохранить и снова получить регистр флагов
  9.         push    eax
  10.         popfd
  11.         pushfd
  12.         pop     eax
  13.         ; Регистр флагов изменился?
  14.         cmp     eax,ebx
  15.         ; Нет, значит команда CPUID не поддерживается
  16.         je      cpuid_not_supported
При вызове инструкция CPUID по содержимому регистра EAX определяет какую информацию о процессоре необходимо вернуть. Вся информация, даже текстовая, возвращается в регистрах EAX, EBX, ECX и EDX. Поэтому, если их значения будут нужны для дальнейшей работы, то перед вызовом СPUID их надо сохранить. При EAX=0 CPUID возвращает в регистрах EBX, ECX и EDX идентификатор производителя процессора (Vendor ID) в виде 12 символов ASCII. В приведенной ниже табличке список самых распространенных идентификаторов производителей процессоров.

ASCII-строкаHEX-значения EBX:EDX:ECXПроизводитель
GenuineIntel756E6547:49656E69:6C65746EIntel
AuthenticAMD68747541:69746E65:444D4163AMD
CyrixInstead69727943:736E4978:64616574Cyrix
CentaurHauls746E6543:48727561:736C7561Centaur
SiS SiS SiS20536953:20536953:20536953SiS
NexGenDriven4778654E:72446E65:6E657669NexGen
GenuineTMx86756E6547:54656E69:3638784DTransmeta
RiseRiseRise65736952:65736952:65736952Rise
UMC UMC UMC20434D55:20434D55:20434D55UMC
Geode by NSC646F6547:79622065:43534E20National Semiconductor

Но это лишь общее название производителя, а нам надо получить полное наименование. Для этого надо последовательно вызвать команду CPUID с параметрами в EAX = 80000002h, 80000003h и 80000004h. На каждый запрос в регистрах EAX:EBX:ECX:EDX будет возвращаться фрагмент 48-символьной строки полного наименования процессора, например, что-то типа Intel(R) Core(TM) i7-3770K CPU @ 3.50GHz. Если строка короче 48 символов, то она будет дополняться пробелами, причем в разных местах. Для удобного получения строки названия процессора я написал вот такую функцию.
  1. ;-------------------------------------------------------------------
  2. ; Функция получения строки названия процессора
  3. ;-------------------------------------------------------------------
  4. ; Параметры:
  5. ;   lpBuff - указатель на строку-приемник
  6. ;   dFixString - надо ли чистить результат от лишних пробелов и
  7. ;            заменять строки (TM) и (R) на отдельные символы
  8. ;-------------------------------------------------------------------
  9. proc    GetCPUString lpBuff:DWORD, dFixString:D