This outputs the manufacturer string associated with your CPU using the CPUID instruction. I wrote this up for a homework assignment, then found out that I didn't need to.
When run on my (virtual) machine, I get the following output:
EAX: 16
EBX: 756e6547
ECX: 6c65746e
EDX: 49656e69
GenuineIntel
What I'd like commented on:
I'm not super-proficient yet in bit manipulation. Originally,
print_register
had afor
loop that iterated themask
directly, likefor (int32_t mask = 0xFF;; mask <<= 8) {
This worked until I realized that I needed to right-shift the result of the bitwise AND, and couldn't figure out how to get the bits shifted from the
mask
. I ended up going for a less efficient solution of iterating bit-counts and creating the mask each iteration. This feels like a naïve approach though.Anything else notable. I'm starting to venture into increasingly unknown territory here, so anything would help.
Note that although inline asm
seems to be considered bad practice to use in many cases, using it was the point of the exercise here. I know wrapper macros exist that would clean this up a bit.
#include <stdio.h>
#include <stdint.h>
void print_register(int32_t reg_value) {
for (int shifted = 0; shifted < 0x20; shifted += 8) {
int32_t mask = 0xFF << shifted;
int32_t matched = (reg_value & mask) >> shifted;
printf("%c", matched);
}
}
int main() {
int32_t out_eax = -1;
int32_t out_ebx = -1;
int32_t out_ecx = -1;
int32_t out_edx = -1;
int32_t leaf = 0;
asm volatile ("cpuid"
: "=a"(out_eax), // 0
"=b"(out_ebx),
"=c"(out_ecx),
"=d"(out_edx)
: "0"(leaf));
printf("EAX: %x\nEBX: %x\nECX: %x\nEDX: %x\n\n",
out_eax, out_ebx, out_ecx, out_edx);
print_register(out_ebx);
print_register(out_edx);
print_register(out_ecx);
printf("\n");
}