Created
April 12, 2017 21:07
-
-
Save s-kostyuk/484e5b0e8b8cd77fe9d02c97da4349dd to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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