C/C++ Как получить серийный номер процессора в Linux

Мне было интересно, как надежно получить серийный номер процессора (PSN) в GNU Linux.

Пока я использую это

#include <stdio.h>
#include <cpuid.h>

unsigned int level = 1;
unsigned eax = 3 /* processor serial number */, ebx = 0, ecx = 0, edx = 0;
__get_cpuid(level, &eax, &ebx, &ecx, &edx);

// byte swap
int first = ((eax >> 24) & 0xff) | ((eax << 8) & 0xff0000) | ((eax >> 8) & 0xff00) | ((eax << 24) & 0xff000000);
int last = ((edx >> 24) & 0xff) | ((edx << 8) & 0xff0000) | ((edx >> 8) & 0xff00) | ((edx << 24) & 0xff000000);

printf("PSN: %08X%08X", first, last);

Это дает мне PSN: A7060200FFFBEBBF,
что соответствует

sudo dmidecode | grep -P '^\s+ID: ([0-9A-F]{2} ){7}[0-9A-F]{2}$'

вывод: ID: A7 06 02 00 FF FB EB BF

Я тестировал только процессоры Intel Core i, поэтому, возможно, он работает только для этого типа процессора.

Я знаю, что «Серийный номер» одинаков для одной и той же модели ЦП и, следовательно, не уникален.

Кроме того, я с нетерпением жду способа добиться этого, который не зависит от выполнения команды оболочки и анализа вывода.


person anni    schedule 16.01.2017    source источник
comment
Надеюсь, это поможет.   -  person GAVD    schedule 16.01.2017
comment
Спасибо, мой фрагмент кода уже вдохновлен этим ответом, но, к сожалению, он для Intel Pentum III. Он также использует изменчивый код asm, предназначенный только для x86, чего я избегаю. Он также использовал другое значение, используемый уровень был 0, что не работало для меня, и он использовал другие регистры, ecx edx, тогда как я eax edx.   -  person anni    schedule 16.01.2017
comment
Это будет работать для AMD, но не для всех процессоров ARM.   -  person David C. Rankin    schedule 16.01.2017
comment
В порядке. Но тогда почему в примере для Intel Pentium III используется другой уровень для получения PSN?   -  person anni    schedule 16.01.2017
comment
Привет @Bap, есть ли у тебя возможность протестировать свой код на других процессорах x86/64? (возможно, Xeon?). Это работает ?   -  person atari83    schedule 24.05.2020


Ответы (1)


вы можете использовать popen, а затем проанализировать результат

unsigned char *pk = new unsigned char[100];
    FILE *source = popen("lscpu", "r");
    while (!feof(source)) {
        fread(pk, 100, 1, source);
        for(int i=0;i<100;++i)
        {
            printf("%c",pk[i]);
        }
        printf("\n");
    }
    pclose(source);
person sam    schedule 16.01.2017
comment
Спасибо, но я ищу решение, которое не зависит от выполнения команды оболочки и получения вывода. - person anni; 16.01.2017