Skip to content

Instantly share code, notes, and snippets.

@s-kostyuk
Created April 12, 2017 21:07
Show Gist options
  • Save s-kostyuk/484e5b0e8b8cd77fe9d02c97da4349dd to your computer and use it in GitHub Desktop.
Save s-kostyuk/484e5b0e8b8cd77fe9d02c97da4349dd to your computer and use it in GitHub Desktop.
// ca_sem6_lab3.cpp: определяет точку входа для консольного приложения.
//
#include <stdio.h>
#include <stdint.h>
bool check_is_32() {
bool is_32;
_asm {
mov is_32, 0; сбрасываем результат
; save_original:
pushf; ( Сохранить исходное состояние регистра флагов )
; collect_detect_data:
pushf; Скопировать регистр флагов...
pop ax; ...в регистр AX
xor ah, 11110000b; Поменять значение старших 4 битов
push ax; Скопировать регистр AX
popf; ...в регистр флагов
pushf; Скопировать регистр флагов...
pop bx; ...в регистр BX
; restore_original:
popf; ( Восстановить исходное состояние регистра флагов )
; analyze_32_bit:
xor ah, bh; AH = 0 ( биты в регистре флагов не поменялись ) → 808x - 80286, иначе 80386 +
mov is_32, ah; save results to boolean value
}
return is_32;
}
bool check_cpuid_supported() {
if ( check_is_32() == false ) {
return false;
}
bool cpuid_supported;
_asm {
mov cpuid_supported, 0; сбрасываем результат
; check_cpuid_support:
; если можно установить и сбросить 21 - й бит ID в EFLAGS → CPUID подерживается
; иначе - поддержка отсутствует
; source: Intel SDM, Vol. 1 3 - 17
; save_original:
pushfd; Скопировать оригинальное состояние регистра флагов
pushfd; Скопировать регистр флагов...
pop eax; ...в регистр EAX
or eax, 200000h; установить 21 - й бит( флаг ID ) в 1
; 200000h - единица, сдвинутая на 21 разряд влево
push eax; Скопировать регистр EAX...
popfd; ...в регистр флагов
pushf; Скопировать регистр флагов...
pop bx; ...в регистр EBX
; restore_original:
popfd; ( Восстановить исходное состояние регистра флагов )
xor eax, ebx; EAH = 0 ( биты в регистре флагов не поменялись ) → CPUID не подерживается, иначе - поддерживается
jz exit; если флаг ID = 0 → CPUID не поддерживается, можно выходить
mov cpuid_supported, 1; иначе - поддержка присутствует
exit:
}
return cpuid_supported;
}
int32_t get_max_cpuid_value() {
if ( check_cpuid_supported() == false ) {
return -1;
}
int32_t max_cpuid_value;
_asm {
; get_max_cpuid_value
mov EAX, 00h; установка входного параметра
cpuid; получение выходных параметров, соответствующих входному
mov max_cpuid_value, eax; сохранение максимального входного параметра
; в EBX : EDX:ECX – строка идентификации производителя( ANSI )
}
return max_cpuid_value;
}
int main()
{
bool is_32 = check_is_32();
bool cpuid_supported = check_cpuid_supported();
int32_t max_cpuid_value = get_max_cpuid_value();
if ( is_32 ) {
printf( "This processor supports 32-bit instructions\n" );
}
else
{
printf( "This processor is 16-bit\n" );
}
if ( cpuid_supported ) {
printf( "This processor supports CPUID instruction\n" );
printf( "Max CPUID input value: %d\n", max_cpuid_value );
}
else
{
printf( "There is no CPUID support for this processor\n" );
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment