CPUの機能を読み出し、それを表示してみましょう。
arques.hatenablog.com
のアゼンブラーバージョンです。
C++ソースリスト
#include <iostream> #include <bitset> using namespace std; extern "C" void myCpuid(int*, int); // assembler function using namespace std; enum _ECX // CpuId(1, 0) { SSE3 = 0, PCLMULQDQ = 1, DTES64 = 2, MONITOR = 3, DS_CPL = 4, VMX = 5, SMX = 6, EST = 7, TM2 = 8, SSSE3 = 9, CNXT_ID = 10, SDBG = 11, FMA = 12, CX16 = 13, XTPR = 14, PDCM = 15, PCID = 17, DCA = 18, SSE41 = 19, SSE42 = 20, X2APIC = 21, MOVBE = 22, POPCNT = 23, TSC_DEADLINE = 24, AES = 25, XSAVE = 26, OSXSAVE = 27, AVX = 28, F16C = 29, RDRND = 30, HYPERVISOR = 31 }; enum _EDX // CpuId(1, 0) { FPU = 0, VME = 1, DE = 2, PSE = 3, TSC = 4, MSR = 5, PAE = 6, MCE = 7, CX8 = 8, APIC = 9, SEP = 11, MTRR = 12, PGE = 13, MCA = 14, CMOV = 15, PAT = 16, PSE_36 = 17, PSN = 18, CLFSH = 19, DS = 21, ACPI = 22, MMX = 23, FXSR = 24, SSE = 25, SSE2 = 26, SS = 27, HTT = 28, TM = 29, IA64 = 30, PBE = 31 }; enum _EBX // CpuId(7, 0) { AVX2 = 5, AVX512F = 16 }; void dipsFeatures(string isa_feature, bitset<32> _REG_, int pos) { cout << isa_feature << (_REG_[pos] ? " supported." : " not supported!") << std::endl; } int main() { int regs[4]; myCpuid(regs, 0); int nMax = regs[0]; if (nMax >= 1) { myCpuid(regs, 1); bitset<32> _EDX_(regs[3]); cout << hex << _EDX_ << endl; dipsFeatures("FPU ", _EDX_, _EDX::FPU); dipsFeatures("VME ", _EDX_, _EDX::VME); dipsFeatures("DE ", _EDX_, _EDX::DE); dipsFeatures("PSE ", _EDX_, _EDX::PSE); dipsFeatures("TSC ", _EDX_, _EDX::TSC); dipsFeatures("MSR ", _EDX_, _EDX::MSR); dipsFeatures("PAE ", _EDX_, _EDX::PAE); dipsFeatures("MCE ", _EDX_, _EDX::MCE); dipsFeatures("CX8 ", _EDX_, _EDX::CX8); dipsFeatures("APIC ", _EDX_, _EDX::APIC); dipsFeatures("SEP ", _EDX_, _EDX::SEP); dipsFeatures("MTRR ", _EDX_, _EDX::MTRR); dipsFeatures("PGE ", _EDX_, _EDX::PGE); dipsFeatures("MCA ", _EDX_, _EDX::MCA); dipsFeatures("CMOV ", _EDX_, _EDX::CMOV); dipsFeatures("PAT ", _EDX_, _EDX::PAT); dipsFeatures("PSE-36 ", _EDX_, _EDX::PSE_36); dipsFeatures("PSN ", _EDX_, _EDX::PSN); dipsFeatures("CLFSH ", _EDX_, _EDX::CLFSH); dipsFeatures("DS ", _EDX_, _EDX::DS); dipsFeatures("ACPI ", _EDX_, _EDX::ACPI); dipsFeatures("MMX ", _EDX_, _EDX::MMX); dipsFeatures("FXSR ", _EDX_, _EDX::FXSR); dipsFeatures("SSE ", _EDX_, _EDX::SSE); dipsFeatures("SSE2 ", _EDX_, _EDX::SSE2); dipsFeatures("SS ", _EDX_, _EDX::SS); dipsFeatures("HTT ", _EDX_, _EDX::HTT); dipsFeatures("TM ", _EDX_, _EDX::TM); dipsFeatures("IA64 ", _EDX_, _EDX::IA64); dipsFeatures("PBE ", _EDX_, _EDX::PBE); bitset<32> _ECX_(regs[2]); dipsFeatures("SSE3 ", _ECX_, _ECX::SSE3); dipsFeatures("PCLMULQDQ ", _ECX_, _ECX::PCLMULQDQ); dipsFeatures("DTES64 ", _ECX_, _ECX::DTES64); dipsFeatures("MONITOR ", _ECX_, _ECX::MONITOR); dipsFeatures("DS_CPL ", _ECX_, _ECX::DS_CPL); dipsFeatures("VMX ", _ECX_, _ECX::VMX); dipsFeatures("SMX ", _ECX_, _ECX::SMX); dipsFeatures("EST ", _ECX_, _ECX::EST); dipsFeatures("TM2 ", _ECX_, _ECX::TM2); dipsFeatures("SSSE3 ", _ECX_, _ECX::SSSE3); dipsFeatures("CNXT_ID ", _ECX_, _ECX::CNXT_ID); dipsFeatures("SDBG ", _ECX_, _ECX::SDBG); dipsFeatures("FMA ", _ECX_, _ECX::FMA); dipsFeatures("CX16 ", _ECX_, _ECX::CX16); dipsFeatures("XTPR ", _ECX_, _ECX::XTPR); dipsFeatures("PDCM ", _ECX_, _ECX::PDCM); dipsFeatures("PCID ", _ECX_, _ECX::PCID); dipsFeatures("DCA ", _ECX_, _ECX::DCA); dipsFeatures("SSE41 ", _ECX_, _ECX::SSE41); dipsFeatures("SSE42 ", _ECX_, _ECX::SSE42); dipsFeatures("X2APIC ", _ECX_, _ECX::X2APIC); dipsFeatures("MOVBE ", _ECX_, _ECX::MOVBE); dipsFeatures("POPCNT ", _ECX_, _ECX::POPCNT); dipsFeatures("TSC_DEADLINE ", _ECX_, _ECX::TSC_DEADLINE); dipsFeatures("AES ", _ECX_, _ECX::AES); dipsFeatures("XSAVE ", _ECX_, _ECX::XSAVE); dipsFeatures("OSXSAVE ", _ECX_, _ECX::OSXSAVE); dipsFeatures("AVX ", _ECX_, _ECX::AVX); dipsFeatures("F16C ", _ECX_, _ECX::F16C); dipsFeatures("RDRND ", _ECX_, _ECX::RDRND); dipsFeatures("HYPERVISOR ", _ECX_, _ECX::HYPERVISOR); } if (nMax >= 7) { myCpuid(regs, 7); bitset<32> _EBX_(regs[1]); dipsFeatures("AVX2 ", _EBX_, _EBX::AVX2); dipsFeatures("AVX512F ", _EBX_, _EBX::AVX512F); } }
アセンブリ関数ソースリスト
__cpuidイントリンシックを、アセンブリ言語の関数で実装します。関数名はmyCpuidです。基本的にmyCpuidは__cpuidイントリンシックと互換があります。
include ksamd64.inc _TEXT segment ; ; rcx = stringの先頭アドレス。 ; rdx = function # ; public myCpuid align 16 myCpuid proc frame ; prologを使う時はproc frame ; prolog rex_push_reg rbx ; マクロでrbxをpush .endprolog ; end of prolog mov r9, rcx ; addr mov eax, edx xor ecx, ecx cpuid mov [r9+0], eax mov [r9+4], ebx mov [r9+8], ecx mov [r9+12], edx ; epilog pop rbx ; restore ret myCpuid endp _TEXT ends end
CPU brand string: 11th Gen Intel(R) Core(TM) i5-1135G7 @ 2.40GHzで実行した例:
FPU supported. VME supported. DE supported. PSE supported. TSC supported. MSR supported. PAE supported. MCE supported. CX8 supported. APIC supported. SEP supported. MTRR supported. PGE supported. MCA supported. CMOV supported. PAT supported. PSE-36 supported. PSN not supported! CLFSH supported. DS supported. ACPI supported. MMX supported. FXSR supported. SSE supported. SSE2 supported. SS supported. HTT supported. TM supported. IA64 not supported! PBE supported. SSE3 supported. PCLMULQDQ supported. DTES64 supported. MONITOR supported. DS_CPL supported. VMX supported. SMX not supported! EST supported. TM2 supported. SSSE3 supported. CNXT_ID not supported! SDBG supported. FMA supported. CX16 supported. XTPR supported. PDCM supported. PCID supported. DCA not supported! SSE41 supported. SSE42 supported. X2APIC supported. MOVBE supported. POPCNT supported. TSC_DEADLINE supported. AES supported. XSAVE supported. OSXSAVE supported. AVX supported. F16C supported. RDRND supported. HYPERVISOR not supported! AVX2 supported. AVX512F supported.