Cogs and Levers A blog full of technical stuff

CPUID

CPUID is an opcode present in the x86 architecture that provides applications with information about the processor.

In today’s article, I’ll show you how to invoke this opcode and extract the information that it holds.

The Opcode

The CPUID opcode is actually rather simple. Using EAX we can control CPUID to output different pieces of information. The following table outlines all of the information available to us.

EAX Description
0 Vendor ID string; maximum CPUID value supported
1 Processor type, family, model, and stepping
2 Cache information
3 Serial number
4 Cache configuration
5 Monitor information
80000000h Extended Vendor ID
80000001h Extended processor type, family model, and stepping
80000002h-80000004h Extended processor name

As you can see, there’s quite a bit of information available to us.

I think that if you were to take a look in /proc/cpuinfo, you would see similar information:

➜  ~ cat /proc/cpuinfo 
processor : 0
vendor_id : GenuineIntel
cpu family  : 6
model   : 142
model name  : Intel(R) Core(TM) i7-7500U CPU @ 2.70GHz
stepping  : 9
. . . 

Processor name

We’ll put together an example that will read out the processor name, and print it to screen.

When CPUID is invoked with a 0 in RAX, the vendor string is split across RBX, RDX and RCX. We need to piece this information together into a printable string.

To start, we need a buffer to store the vendor id. We know that the id will come back in 3 chunks of 4-bytes each; so we’ll reserve 12 bytes in total.

section .bss
    vendor_id:   resb 12 

The program starts and we execute cpuid. After that, we stuff it into the vendor_id buffer that’s been pre-allocated.

section .text
    global _start

_start:
    mov   rax, 0
    cpuid

    mov   rdi, vendor_id
    mov   [rdi], ebx
    mov   [rdi + 4], edx
    mov   [rdi + 8], ecx

Print it out to screen using the linux system call write.

    mov   rax, 4
    mov   rbx, 1
    mov   rcx, vendor_id
    mov   rdx, 12
    int   0x80

. . and, get out

    mov   rax, 1
    mov   rbx, 0
    int   0x80

Testing

Assembling and executing this code is pretty easy.

$ nasm -f elf64 -g cpuid.asm
$ ld -s -o cpuid cpuid.o    
$ ./cpuid 
GenuineIntel

From here

There are so many other system services that will allow you to view data about your processor. Going through the documentation, you’ll create yourself a full cpuinfo replica in no time.