#include #include typedef unsigned long uint32_t; static uint32_t hex_decode(char *p) { uint32_t val = 0; while (1) { if (*p >= '0' && *p <= '9') { val = (val << 4) | (*p - '0'); } else if (*p >= 'A' && *p <= 'F') { val = (val << 4) | (*p - 'A' + 10); } else if (*p >= 'a' && *p <= 'f') { val = (val << 4) | (*p - 'a' + 10); } else { break; } p++; } return val; } static void rdmsr(uint32_t *ecx, uint32_t *eax, uint32_t *edx) { #asm push bp mov bp, sp cli ; disable interrupt push eax push ebx push ecx push edx push edi mov bx, [bp+4] ; bp+4: argument #1 (pointer) mov ecx, [bx] mov edi, #0x9c5a203a ; password of "AMD private MSR" rdmsr mov bx, [bp+6] ; bp+6: argument #2 (pointer) mov [bx], eax mov bx, [bp+8] ; bp+8: argument #3 (pointer) mov [bx], edx pop edi pop edx pop ecx pop ebx pop eax sti ; enable interrupt pop bp #endasm return; } int main(int argc, char *argv[]) { int err; uint32_t ecx, eax, edx, lo, hi, t; /* check argument */ if (argc < 2) { printf("usage: rdmsr [hex value(0-ffffffff)]\n"); err = EXIT_FAILURE; goto fin0; } /* get MSR index */ if (argc < 3) { lo = hi = hex_decode(argv[1]); } else { lo = hex_decode(argv[1]); hi = hex_decode(argv[2]); } if (lo > hi) { t = lo; lo = hi; hi = t; } /* dump MSR value */ for (ecx = lo; ecx <= hi; ecx++) { rdmsr(&ecx, &eax, &edx); printf("[%08lx] %08lx:%08lx\n", ecx, edx, eax); if (ecx == (uint32_t)0xffffffff) break; // final value } err = EXIT_SUCCESS; fin0: return err; }