In Windows X86, the CPU brand can be queried with cpuid
intrinsic function.
Here is a sample of the code:
#include <stdio.h>
#include <intrin.h>
int main(void)
{
int cpubrand[4 * 3];
__cpuid(&cpubrand[0], 0x80000002);
__cpuid(&cpubrand[4], 0x80000003);
__cpuid(&cpubrand[8], 0x80000004);
char str[48];
memset(str, 0, sizeof str);
memcpy(str, cpubrand, sizeof cpubrand);
printf("%s\n", str);
}
What is the alternative of this in Windows ARM64?
Although probably not the answer you're looking for (i.e. directly interrogating the CPU), you can fetch the "ProcessorNameString" value from the Windows Registry using code like the following:
#define BUFSIZ 64 // For easy adjustment of limits, if required
char answer[BUFSIZ] = "Error Reading CPU Name from Registry!", inBuffer[BUFSIZ] = "";
const char *csName = "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0";
HKEY hKey; DWORD gotType, gotSize = BUFSIZ;
if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, csName, 0, KEY_READ, &hKey) == ERROR_SUCCESS) {
if (!RegQueryValueExA(hKey, "ProcessorNameString", nullptr, &gotType, (PBYTE)(inBuffer), &gotSize)) {
if ((gotType == REG_SZ) && strlen(inBuffer)) strcpy(answer, inBuffer);
}
RegCloseKey(hKey);
}
This will (or should) give you the processor's 'name' that the Windows system sees! I don't have access to an ARM64
system, so I can't properly test it but, on my x64
system, I get the following (correct) string: Intel(R) Core(TM) i7-8550U CPU @ 1.80GHz
(which is exactly that returned by using __cpuid()
calls to get the "Brand String").
However, like you, I would be very interested to know of a way to do this directly - i.e., how would the Windows O/S get this info on an ARM64
system?
Not a way to get name directly from the CPU either, but you can get processor name from the WMI Win32_Processor class
It can be obtained by running wmic cpu get name
in cmd or (Get-WmiObject Win32_Processor).Name
in PowerShell. Getting it from C# is also easy, something like
ManagementObjectSearcher mos = new ManagementObjectSearcher("SELECT Name FROM Win32_Processor")
foreach (ManagementObject mo in mos.Get())
{
Console.WriteLine(mo["Name"]);
}
However doing that from C is a lot trickier. Luckily there's already a similar example in this answer. The main part should be like this
BSTR query = SysAllocString(L"SELECT Name FROM Win32_Processor");
hr = services->lpVtbl->ExecQuery(services, language, query, WBEM_FLAG_BIDIRECTIONAL, NULL, &results);
...
hr = result->lpVtbl->Get(result, L"Name", 0, &name, 0, 0);
SysFreeString(query);
The direct way to get this information would be to read the Main ID Register MIDR_EL1
. This could be done via the mrs
instruction in (inline) assembly or via the _ReadStatusReg
instrinct.
Unfortunately this register cannot be accessed from user mode (i.e. EL0
) and every attempt throws an exception. At Linux the behavior is then emulated so that MIDR_EL1
can still be accessed. However, I do not know or have the opportunity to test whether Windows also offers this feature.
References:
MIDR_EL1
accessible)User contributions licensed under CC BY-SA 3.0