From 6aa2f783a8a18589ae66e85f781f86b08abb3397 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ciro=20Santilli=20=E5=85=AD=E5=9B=9B=E4=BA=8B=E4=BB=B6=20?= =?UTF-8?q?=E6=B3=95=E8=BD=AE=E5=8A=9F?= Date: Mon, 17 Jun 2019 00:00:00 +0000 Subject: [PATCH] x86 asm: CPUID mov in from x86-assembly-cheat --- README.adoc | 38 ++++++++++++++++++++++++++++++++++++ userland/arch/x86_64/cpuid.S | 33 +++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+) create mode 100644 userland/arch/x86_64/cpuid.S diff --git a/README.adoc b/README.adoc index 46679d5..a60b6e1 100644 --- a/README.adoc +++ b/README.adoc @@ -12506,6 +12506,44 @@ Generated some polemic when kernel devs wanted to use it as part of `/dev/random RDRAND sets the carry flag when data is ready so we must loop if the carry flag isn't set. +==== x86 CPUID instruction + +Example: link:userland/arch/x86_64/cpuid.S[CPUID] + +Fills EAX, EBX, ECX and EDX with CPU information. + +The exact data to show depends on the value of EAX, and for a few cases instructions ECX. When it depends on ECX, it is called a sub-leaf. Out test program prints `eax == 0`. + +On <> for example the output EAX, EBX, ECX and EDX are: + +.... +0x00000016 +0x756E6547 +0x6C65746E +0x49656E69 +.... + +EBX and ECX are easy to interpret: + +* EBX: 75 6e 65 47 == 'u', 'n', 'e', 'G' in ASCII +* ECX: 6C 65 74 6E == 'l', 'e', 't', 'n' + +so we see the string `Genu ntel` which is a shorthand for "Genuine Intel". Ha, I wonder if they had serious CPU pirating problems in the past? :-) + +Information available includes: + +* vendor +* version +* features (mmx, simd, rdrand, etc.) +* caches +* tlbs http://en.wikipedia.org/wiki/Translation_lookaside_buffer + +The cool thing about this instruction is that it allows you to check the CPU specs and take alternative actions based on that inside your program. + +On Linux, the capacity part of this information is parsed and made available at `cat /proc/cpuinfo`. See: http://unix.stackexchange.com/questions/43539/what-do-the-flags-in-proc-cpuinfo-mean + +There is also the `cpuinfo` command line tool that parses the CPUID instruction from the command line. Source: http://www.etallen.com/cpuid.html + === x86 x87 FPU instructions <> 5.2 "X87 FPU INSTRUCTIONS" diff --git a/userland/arch/x86_64/cpuid.S b/userland/arch/x86_64/cpuid.S new file mode 100644 index 0000000..1b3a134 --- /dev/null +++ b/userland/arch/x86_64/cpuid.S @@ -0,0 +1,33 @@ +/* https://github.com/cirosantilli/linux-kernel-module-cheat#x86-cpuid-instruction */ + +#include + +LKMC_PROLOGUE + mov $0, %eax + cpuid + + /* Save the other registers. */ + mov %ebx, %r12d + mov %ecx, %r13d + mov %edx, %r14d + + /* eax */ + mov %eax, %edi + call lkmc_print_hex_32 + call lkmc_print_newline + + /* ebx */ + mov %r12d, %edi + call lkmc_print_hex_32 + call lkmc_print_newline + + /* ecx */ + mov %r13d, %edi + call lkmc_print_hex_32 + call lkmc_print_newline + + /* edx */ + mov %r14d, %edi + call lkmc_print_hex_32 + call lkmc_print_newline +LKMC_EPILOGUE