Em ambos os fabricantes, o levantamento proposto é executado pela função 1 da CPUID. Isto signfica que teremos que mover o valor 1 para o registrador EAX, que armazena o código da função a ser executada. Os valores que buscamos são armazenados pela instrução CPUID no registrador EDX.
var REGEDX : LongWord;
begin
asm
MOV EAX, 1
CPUID
MOV [REGEDX], EDX
end;
{ ... }
begin
asm
MOV EAX, 1
CPUID
MOV [REGEDX], EDX
end;
{ ... }
Então, após a execução do código acima, teremos na variável REGEDX o mapa de bits para as características presentes no processador. São 32 bits ao todo, cada um sinalizando se um determinado recurso está presente na CPU do seu computador. Portanto, para ter acesso a cada bit isoladamente, teremos que trabalhar com aritmética binária no Delphi - principalmente com o operador AND aplicado bit a bit.
A ideia é preparar outra variável com 32 bits mas apenas um dos bits estará ligado de cada vez. Ao aplicar o AND binário entre essa variável e o conteúdo de REGEDX nós obtemos a sinalização se o recurso representado nesse bit específico está presente ou não. A imagem abaixo ilustra a extração do recurso representado pelo primeiro bit:
Repare que, na variável preparada, apenas o primeiro bit está ligado, isto é, possui valor 1. Comos os demais bits estão em zero, o AND binário com o REGEDX retornará um valor diferente de zero caso seu primeiro bit também esteja ligado.
Para ligar um bit de cada vez na variável, podemos montar um laço iniciando em 1 (liga o primeiro bit) e ir multiplicando-a por 2 para fazer o bit ir "avançando" :
var REGEDX, Mascara : LongWord;
Suportado : array[0..31] of byte;
i : integer;
begin
{ ... }
Mascara := 1;
for i := 0 to 31 do begin
if (REGEDX and Mascara) <> 0 then
Suportado[i] := 1 { Suportado }
else
Suportado[i] := 0; { Não suportado }
Mascara := Mascara * 2;
end;
{ ... }
Suportado : array[0..31] of byte;
i : integer;
begin
{ ... }
Mascara := 1;
for i := 0 to 31 do begin
if (REGEDX and Mascara) <> 0 then
Suportado[i] := 1 { Suportado }
else
Suportado[i] := 0; { Não suportado }
Mascara := Mascara * 2;
end;
{ ... }
No código acima, a variável preparada para auxiliar na extração dos bits chama-se Mascara. Ao final da execução desse trecho, teremos em cada posição do array Suportado um sinal indicando se o recurso existe ou não na CPU. Mas qual recurso ?
O significado de cada posição varia de acordo com o fabricante da CPU, sendo que até mesmo o conjunto de recursos incluídos em um e outro é diferente. Para facilitar a exibição das informações sobre os recursos podemos montar um array com 32 posições para texto e alimentar cada uma com um lembrete do significado do recurso. O quadro abaixo mostra os recursos disponíveis em processadores Intel:
if(StrComp(VendorID, 'GenuineIntel') = 0)
then begin
Recurso[0]:='FPU'; { Floating Point Unit }
Recurso[1]:='VME'; { Virtual Mode Extension }
Recurso[2]:='DE'; { Debugging Extension }
Recurso[3]:='PSE'; { Page Size Extension }
Recurso[4]:='TSC'; { Time Stamp Counter }
Recurso[5]:='MSR'; { Model Specific Registers }
Recurso[6]:='PAE'; { Physical Address Extension }
Recurso[7]:='MCE'; { Machine Check Extension }
Recurso[8]:='CX8'; { CMPXCHG8 Instruction}
Recurso[9]:='APIC'; { On-chip APIC Hardware }
Recurso[10]:=''; { Reserved }
Recurso[11]:='SEP'; { Fast system call }
Recurso[12]:='MTRR'; { Machine Type Range Registers }
Recurso[13]:='PGE'; { Global Paging Extension }
Recurso[14]:='MCA'; { Machine Check Architecture }
Recurso[15]:='CMOV'; { Conditional Move Instruction }
Recurso[16]:='PAT'; { Page Attribute Table }
Recurso[17]:='PSE-36'; { 36-bit Page Size Extension }
Recurso[18]:='PSN'; { 96-bit Processor Serial Number }
Recurso[19]:='CLFSH'; { CLFLUSH Instruction }
Recurso[20]:=''; { Reserved }
Recurso[21]:='DS'; { Debug Trace Store }
Recurso[22]:='ACPI'; { ACPI Support }
Recurso[23]:='MMX'; { MMX Technology }
Recurso[24]:='FXSR'; { FXSAVE FXRSTOR (Fast save and restore) }
Recurso[25]:='SSE'; { Streaming SIMD Extensions }
Recurso[26]:='SSE2'; { Streaming SIMD Extensions 2 }
Recurso[27]:='SS'; { Self-Snoop }
Recurso[28]:='HTT'; { Hyper-Threading Technology }
Recurso[29]:='TM'; { Thermal Monitor Supported }
Recurso[30]:=''; { Reserved }
Recurso[31]:='PBE'; { Pending Break Enable }
end;
then begin
Recurso[0]:='FPU'; { Floating Point Unit }
Recurso[1]:='VME'; { Virtual Mode Extension }
Recurso[2]:='DE'; { Debugging Extension }
Recurso[3]:='PSE'; { Page Size Extension }
Recurso[4]:='TSC'; { Time Stamp Counter }
Recurso[5]:='MSR'; { Model Specific Registers }
Recurso[6]:='PAE'; { Physical Address Extension }
Recurso[7]:='MCE'; { Machine Check Extension }
Recurso[8]:='CX8'; { CMPXCHG8 Instruction}
Recurso[9]:='APIC'; { On-chip APIC Hardware }
Recurso[10]:=''; { Reserved }
Recurso[11]:='SEP'; { Fast system call }
Recurso[12]:='MTRR'; { Machine Type Range Registers }
Recurso[13]:='PGE'; { Global Paging Extension }
Recurso[14]:='MCA'; { Machine Check Architecture }
Recurso[15]:='CMOV'; { Conditional Move Instruction }
Recurso[16]:='PAT'; { Page Attribute Table }
Recurso[17]:='PSE-36'; { 36-bit Page Size Extension }
Recurso[18]:='PSN'; { 96-bit Processor Serial Number }
Recurso[19]:='CLFSH'; { CLFLUSH Instruction }
Recurso[20]:=''; { Reserved }
Recurso[21]:='DS'; { Debug Trace Store }
Recurso[22]:='ACPI'; { ACPI Support }
Recurso[23]:='MMX'; { MMX Technology }
Recurso[24]:='FXSR'; { FXSAVE FXRSTOR (Fast save and restore) }
Recurso[25]:='SSE'; { Streaming SIMD Extensions }
Recurso[26]:='SSE2'; { Streaming SIMD Extensions 2 }
Recurso[27]:='SS'; { Self-Snoop }
Recurso[28]:='HTT'; { Hyper-Threading Technology }
Recurso[29]:='TM'; { Thermal Monitor Supported }
Recurso[30]:=''; { Reserved }
Recurso[31]:='PBE'; { Pending Break Enable }
end;
Veja este link para saber como obter o nome do fabricante. A documentação sobre o uso do CPUID em processadores Intel pode ser acessada aqui.
O quadro abaixo mostra os recursos disponíveis em processadores AMD:
if(StrComp(VendorID, 'AuthenticAMD') = 0)
then begin
Recurso[0]:='FPU'; { Floating Point Unit }
Recurso[1]:='VME'; { Virtual Mode Extension }
Recurso[2]:='DE'; { Debugging Extension }
Recurso[3]:='PSE'; { Page Size Extension }
Recurso[4]:='TSC'; { Time Stamp Counter }
Recurso[5]:='MSR'; { Model Specific Registers }
Recurso[6]:='PAE'; { Physical Address Extesnion }
Recurso[7]:='MCE'; { Machine Check Extension }
Recurso[8]:='CX8'; { CMPXCHG8 Instruction }
Recurso[9]:='APIC'; { On-chip APIC Hardware }
Recurso[10]:=''; { Reserved }
Recurso[11]:='SEP'; { SYSENTER and SYSEXIT instructions }
Recurso[12]:='MTRR'; { Machine Type Range Registers }
Recurso[13]:='PGE'; { Global Paging Extension }
Recurso[14]:='MCA'; { Machine Check Architecture }
Recurso[15]:='CMOV'; { Conditional Move Instruction }
Recurso[16]:='PAT'; { Page Attribute Table }
Recurso[17]:='PSE-36'; { 36-bit Page Size Extension }
Recurso[18]:=''; { Reserved }
Recurso[19]:='CLFSH'; { CLFLUSH instruction support }
Recurso[20]:=''; { Reserved }
Recurso[21]:=''; { Reserved }
Recurso[22]:=''; { Reserved }
Recurso[23]:='MMX'; { MMX Technology }
Recurso[24]:='FXSR'; { FXSAVE FXRSTOR (Fast save and restore) }
Recurso[25]:='SSE'; { Streaming SIMD Extensions }
Recurso[26]:='SSE2'; { SSE2 instruction support }
Recurso[27]:=''; { Reserved }
Recurso[28]:='HTT'; { Hyper-Threading Technology }
Recurso[29]:=''; { Reserved }
Recurso[30]:=''; { Reserved }
Recurso[31]:=''; { Reserved }
end;
then begin
Recurso[0]:='FPU'; { Floating Point Unit }
Recurso[1]:='VME'; { Virtual Mode Extension }
Recurso[2]:='DE'; { Debugging Extension }
Recurso[3]:='PSE'; { Page Size Extension }
Recurso[4]:='TSC'; { Time Stamp Counter }
Recurso[5]:='MSR'; { Model Specific Registers }
Recurso[6]:='PAE'; { Physical Address Extesnion }
Recurso[7]:='MCE'; { Machine Check Extension }
Recurso[8]:='CX8'; { CMPXCHG8 Instruction }
Recurso[9]:='APIC'; { On-chip APIC Hardware }
Recurso[10]:=''; { Reserved }
Recurso[11]:='SEP'; { SYSENTER and SYSEXIT instructions }
Recurso[12]:='MTRR'; { Machine Type Range Registers }
Recurso[13]:='PGE'; { Global Paging Extension }
Recurso[14]:='MCA'; { Machine Check Architecture }
Recurso[15]:='CMOV'; { Conditional Move Instruction }
Recurso[16]:='PAT'; { Page Attribute Table }
Recurso[17]:='PSE-36'; { 36-bit Page Size Extension }
Recurso[18]:=''; { Reserved }
Recurso[19]:='CLFSH'; { CLFLUSH instruction support }
Recurso[20]:=''; { Reserved }
Recurso[21]:=''; { Reserved }
Recurso[22]:=''; { Reserved }
Recurso[23]:='MMX'; { MMX Technology }
Recurso[24]:='FXSR'; { FXSAVE FXRSTOR (Fast save and restore) }
Recurso[25]:='SSE'; { Streaming SIMD Extensions }
Recurso[26]:='SSE2'; { SSE2 instruction support }
Recurso[27]:=''; { Reserved }
Recurso[28]:='HTT'; { Hyper-Threading Technology }
Recurso[29]:=''; { Reserved }
Recurso[30]:=''; { Reserved }
Recurso[31]:=''; { Reserved }
end;
A documentação sobre o uso do CPUID em processadores AMD pode ser acessada aqui.
Ambos os arrays montados neste post - Suportado e Recurso - estão sincronizados. Então, para mostrar se um recurso está ou não presente basta percorrer os arrays usando o mesmo índice e mostrando lado a lado o nome do recurso e o flag indicativo de suporte a este recurso.