Nesta seção será descrito um programa feito por Jeff Prosise retirado da revista PC MAGAZINE BRASIL de abril de 1995. Chama-se WHATCPU e simplesmente coloca na tela uma mensagem identificando o processador da máquina em que está rodando, não entra em detalhes sobre diferentes tipos de um mesmo chip: SX, DX, DX2, DX4.
PROCESSADORES 8086 e 8088
Apareceram nos primeiros PCs IBM e compatíveis. Eram bastante idênticos, o 8086 tinha 16 linhas de dados, fornecendo ao barramento de dados uma interface de 16 bits. Por outro lado, o 8088 só apresentava 8 linhas de dados, com uma interface de 8 bits. Como se nota, o 8086 era mais rápido, uma vez que era capaz de transportar uma palavra de 16 bits inteira de ou para o barramento de dados numa operação. Já o 8088 precisava de duas operações de 1 byte (8 bits) cada. Fora isso, o funcionamento dos dois processadores era similar, utilizando o mesmo conjunto de instruções e contendo 20 linhas de endereçamento, ou seja, acesso a 1Mb.
Todos os membros da família x86 contêm um registrador FLAGS, que identifica o estado atual do processador. Os bits de 12 a 15 deste registrador estão sempre ativados (ativado significa conter o valor 1) no caso do 8086/8088, não importando o quanto se tente desativá-los. O que o programa WHATCPU faz é tentar ativar os bits 12 e 14 e limpar os bits 13 e 15, utilizando um sequência de instruções que copia os valores do registrador de e para a pilha, usando instruções AND e OR. Se os bits 12 a 15 permanecerem ativados, então o processador deve ser um 8086.
PROCESSADOR 80286
Sucessor dos processadores 8086 e 8088, foi utilizado pela primeira vez no IBM PC/AT. Com o 80286 surgiram o modo protegido e quatro linhas novas de endereçamento, passando para 24 linhas no total, o que se traduzia num acesso de até 16Mb. Da mesma forma, é possível identificar este processador através dos bits de 12 a 15 do registrador FLAGS. Se estes bits estão sempre ativados num 8086 ou 8088, estão desativados num 80286 em modo real. Quando o teste que o programa executa é falso para o 8086 ou 8088, é verificado se os bits de 12 a 15 estão desativados. Se estiverem, é porque o processador deve ser um 80286.
PROCESSADOR 80386
Aumentou ainda mais a capacidade de endereçamento e introduziu o modo virtual (V86). O 80386 possuía 32 linhas de endereçamento, acesso de até 4Gb. O modo V86 veio permitir a execução dos programas mais antigos em máquinas virtuais (VM ou Virtual Machines) como se fosse em modo real, conjuntamente com outros programas em modo protegido. O 80386 tinha duas versões, uma DX e uma SX. O 80386SX continha somente 24 linhas de endereçamento, enquanto que o 80386DX tinha 32 linhas. Contudo, do ponto de vista do software, eram idênticos. A diferença estava na largura da interface para barramento de dados.
No 80386, o registrador FLAGS foi expandido de 16 para 32 bits e passou a se chamar EFLAGS. O bit 18 do registrador EFLAGS não foi definido e não poderá ser ativado. No 80486 este bit tornou-se o Alignment Check (AC), utilizado para capturar acessos à memória não-alinhados (tentativas de ler uma palavra num endereço que reside nos limites de um byte).
Desta forma, o programa lê o registrador EFLAGS e tenta ativar o bit AC. Se o valor do bit não puder ser alterado, o programa pode concluir que a máquina é um 80386 e responde de acordo.
PROCESSADOR 80486, PENTIUM e OUTROS
O 80486 trouxe avanços sobre a linha 80386, projetados para elevar o desempenho. Trouxe incorporado no chip um código unificado e um cache de dados compostos de veloz RAM estática. A versão DX contém um coprocessador matemático integrado ou unidade de ponto flutuante (FPU ou Flooting Point Unit). Os modelos SX são equivalentes, só que com a FPU desativada. Os demais modelos 80486DX2 e 80486DX4 pertencem à classe DX, utilizam tecnologia multiplicadora de relógio para melhorar o desempenho.
O Pentium trouxe mais velocidade aos processadores da família x86. Tem uma interface de 64 bits para o barramento de dados, arquitetura superescalar (pode executar mais de uma instrução ao mesmo tempo), caches de códigos e de dados separados e uma FPU com pipeline.
Com a desativação dos processadores 8086, 8088, 80286 e 80386, um programa pode distinguir CPUs 80486SX, 80486DX e 80486DX2 de CPUs 80486DX4 e Pentium através de tentativas de ativação do bit 21 do registrador EFLAGS. Tanto no 80486DX4, quanto no Pentium, este bit é conhecido como bit ID. Estes dois últimos processadores incorporaram uma nova instrução chamada CPUID, que retorna a informação de identificação da CPU. Se o bit ID não puder ser alterado, é sinal seguro de que a CPU é um 80486 (o programa WHATCPU tenta ativar este bit, se não consegue é porque a máquina é um 80486). Entretanto se o bit ID puder ser ativado, devem ser realizados testes adicionais para determinar se o processador é um 80486DX4, um Pentium, ou processador mais recente.
Se a instrução CPUID for chamada com o registrador EAX contendo o valor 1, o retorno da instrução será depositado no próprio registrador EAX, identificando o nível de passo da CPU (semelhante a um número de versão para software), modelo e família. O termo família, neste caso, se refere ao 80486, Pentium, etc. O código ID identificador de família está contido nos bits 8 a 11. Para separar os processadores Pentium de outras CPUs, o programa executa uma instrução CPUID e examina o resultante código ID de família. Um Pentium é identificado pelo valor 5, um valor 4 identifica um 80486DX4.
O programa WHATCPU foi feito numa época onde ainda não existiam processadores como o MMX, desta forma novas CPUs poderão retornar diferentes códigos ID de família. Tentando driblar esta situação, o programa mostra o código ID de família seguido por "86", para códigos diferentes de 4 ou 5. Entretanto é provável que o programa não funcione perfeitamente com os sucessores do Pentium.
A seguir está a listagem do programa WHATCPU:
;Programa de Jeff Prosise, PC Magazine Abr 1995.
;E-mail: pcmagbr@eab.com.br
CPUID MACRO
db 00Fh, 0A2h
;Macro para a instrução
CPUID
ENDM
code segment
assume
cs:code, ds:code
org 100h
begin: jmp short main
msg_8086 db "É
um 8086 ou um 8088!",13,10,"$"
msg_286 db "É
um 286!",13,10,"$"
msg_386 db "É
um 386!",13,10,"$"
msg_486 db "É
um 486!",13,10,"$"
msg_586 db "É
um Pentium!",13,10,"$"
msg_other db "É
um ?86!",13,10,"$"
main proc near
;
; Procura um 8086 ou 8088 tentando limpar os bits de 12 a 15 do registrador
; FLAGS. Num 8086 ou 8088, estes bits estão
sempre ativados.
;
mov dx,offset
msg_8086
;Assume 8086/88
cli
;Desativa
interrupções
pushf
;Salva
FLAGS
pushf
;Empilha
FLAGS
pop
ax
;Desempilha
FLAGS em AX
and
ax, 0FFFh
;Limpa bits 12 a 15
or
ax, 5000h
;Ativa bits 12 e 14
push
ax
;Empilha
AX
popf
;Desempilha
AX em FLAGS
pushf
;Empilha
FLAGS
pop
ax
;Desempilha
FLAGS em AX
popf
;Restaura
FLAGS
sti
;Ativa
interrupções
and
ax, 0F000h
;Limpa bits de 0 a 11
cmp
ax, 0F000h
;Bits 12 a 15 estão ativados?
jne
check_286
;Não, então é um 286 ou superior
jmp
done
;Sim, então
é um 8086/88
;
; Procura um 286 verificando se os bits de 12 a 15 estão limpos
após a
; operação anterior. Num 286 executado em modo real,
estes bits estarão
; sempre limpos.
;
check_286: mov dx, offset msg_286
;Assume 286
or
ax, ax
;Bits de 12 a 15
estão limpos?
jne
check_386
;Não, então é um 386 ou superior
jmp
done
;Sim, é
um 286
;
; Procura um 386 tentando ativar o bit Alignment Check (AC)
do registrador
; EFLAGS. Este bit não pode ser mudado num
386.
;
.386
check_386: mov dx, offset msg_386 ;Assume 386
cli
;Desativa
interrupções
pushfd
;Salva
EFLAGS
pushfd
;Empilha EFLAGS
pop
eax
;Desempilha
EFLAGS em EAX
mov
ebx, eax
;Armazena EAX em EBX
xor
eax, 40000h
;Alterna
bit 18
push
eax
;Empilha EAX
popfd
;Desempilha
EAX em FLAGS
pushfd
;Empilha em
FLAGS
pop
eax
;Desempilha
EFLAGS em EAX
popfd
;Restaura
EFLAGS
sti
;Ativa interrupções
and
eax, 40000h
;Limpa todos os bits, exceto o bit 18
and
ebx, 40000h
;em EAX e EBX
cmp
eax, ebx
;Compara EAX e EBX
je
done
;Se
forem iguais, então é um 386
;
; Procura um 486 tentando ativar o bit ID do
registrador EFLAGS. Este bit
; não pode ser ativado na maioria dos 486s.
;
mov dx, offset msg_486
;Assume
486
cli
;Desativa interrupções
pushfd
;Salva EFLAGS
pushfd
;Empilha EFLAGS
pop eax
;Desempilha
ELFLAGS em EAX
mov ebx, eax
;Armazena EAX em
EBX
xor eax, 200000h
;Alterna bit 21
push eax
;Empilha EAX
popfd
;Desempilha EAX em
EFLAGS
pushfd
;Empilha EFLAGS
pop eax
;Desempilha EFLAGS em EAX
popfd
;Restaura EFLAGS
sti
;Ativa interrupções
and eax,
200000h
;Limpa todos os
bits, exceto o bit 21
and ebx, 200000h
;em EAX e
EBX
cmp eax, ebx
;Compara EAX
e EBX
je done
;Se forem iguais, então é um 486
;
; Tivemos sucesso ao alterar o bit ID do processador.
Provavelmente é um
; Pentium ou posterior. Mas poderia ser um 486. Por isso, tenha
cuidado.
; Para identificar o processador, use o código ID
de família informado
; pela instruçao CPUID.
;
mov eax,1
;Obtém
o ID da CPU
CPUID
;Via instrução CPUID
and eax, 0F00h
;Limpa todos os bits, exceto os de
8 a 11
shr eax, 8
;Desloca 8 casas para a direita (EAX=ID
família)
mov dx, offset msg_586
;Assume Pentium
cmp eax, 5
;O ID da família é 5?
je done
;Sim, então é um Pentium
add al, 30h
;Não
é um Pentium,
mov byte ptr msg_other[5],al
;então reporta o ID
mov dx, offset msg_other
;da família diretamente
;
; Mostre o tipo de processador e encerre a sessão.
;
done:
mov ah, 09h
;Mostra a mensagem
int
21h
;"É um ..."
mov ah,
4Ch
;Retorna ao S.O.
int
21h
;via função 4Ch
main endp
code ends
end begin
![]() Powered by WebGlimpse |
|