Код:
; ********************************************************************
; * *
; * CPU v2.2 (c) Septiembre 1992 CiriSOFT *
; * (c) Grupo Universitario de Informática - Valladolid *
; * *
; * Este programa determina el tipo de microprocesador del equipo *
; * y devuelve un código ERRORLEVEL indicándolo: *
; * *
; * 0-8088, 1-8086, 2-NEC V20, 3-NEC V30, *
; * 4-80188, 5-80186, 6-286, 7-386, 8-486 *
; * *
; * Aviso: Utilizar TASM 2.0 o compatible exclusivamente. *
; * *
; ********************************************************************
cpu SEGMENT
ASSUME CS:cpu, DS:cpu
.386
ORG 100h
inicio:
LEA DX,texto_ini ; texto de saludo
MOV AH,9
INT 21h ; imprimirlo
CALL procesador? ; tipo de procesador en AX
PUSH AX ; guardarlo para el final
LEA BX,cpus_indice-2 ; tabla de nombres-2
MOV CX,0FFFFh ; número de iteración-1
otro_proc: INC CX
ADD BX,2
MOV DX,[BX] ; nombre del primer procesador
CALL print
CMP CX,AX ; ¿procesador del equipo?
JNE no_es_este
LEA DX,apuntador_txt ; sí lo es: indicarlo
CALL print
no_es_este: LEA DX,separador_txt
CALL print
CMP CX,7 ; número de CPUs tratadas-1
JBE otro_proc
LEA DX,texto_fin ; últimos caracteres
CALL print
MOV AH,4Ch ; retornar código errorlevel AL
INT 21h ; fin de programa
procesador? PROC ; devolver el tipo de microprocesador en AX
PUSHF
PUSH DS
PUSH ES
PUSH CX
PUSH DX
PUSH DI
PUSH SI
MOV AX,CS
MOV DS,AX ; durante la rutina se guardará
MOV ES,AX ; el tipo de procesador en DL:
MOV DL,6 ; supuesto un 286 (DL=6) ...
PUSHF
POP AX ; AX = flags
AND AX,0FFFh ; borrar nibble más significativo
PUSH AX
POPF ; intentar poner a 0 los 4 bits más
PUSHF ; significativos de los flags
POP AX
AND AX,0F000h ; seguirán valiendo 1 excepto en
CMP AX,0F000h ; un 80286 o superior
JE ni286ni_super
PUSHF ; es 286 o superior
POP AX
OR AX,7000h ; intentar activar bit 12, 13 ó 14
PUSH AX
POPF
PUSHF
POP AX
AND AX,7000h ; 286 pone bits 12, 13 y 14 a cero
JZ cpu_hallada ; es un 286 (DL=6)
INC DL ; es un 386 (DL=7) ... de momento
PUSH DX
CLI ; momento crítico
MOV EDX,ESP ; preservar ESP en EDX
AND ESP,0FFFFh ; borrar parte alta de ESP
AND ESP,0FFFCh ; forzar ESP a múltiplo de 4
PUSHFD ; guardar flags en pila (32 bits)
POP EAX ; recuperar flags en EAX
MOV ECX,EAX
XOR EAX,40000h ; conmutar bit 18
PUSH EAX
POPFD ; intentar cambiar este bit
PUSHFD
POP EAX ; ECX conserva el bit inicial
XOR EAX,ECX ; bit 18 de EAX a 1 si cambió
SHR EAX,12h ; mover bit 18 a bit 0
AND EAX,1 ; dejar sólo ese bit
PUSH ECX
POPFD ; restaurar bit 18 de los flags
MOV ESP,EDX ; restaurar ESP
STI ; permitir interrupciones de nuevo
POP DX ; recuperar tipo de CPU en DL
CMP AX,0
JE cpu_hallada ; es 386: DL=7 (bit 18 no cambió)
INC DL ; es 486: DL=8 (bit 18 cambió)
JMP cpu_hallada
ni286ni_super: MOV DL,4 ; supuesto un 80188 ...
MOV AX,0FFFFh
MOV CL,33
SHL AX,CL ; (80188/80186 toman CL mod 32)
JNZ tipo_bus_proc ; ... lo es, calcular bus (188/186)
MOV DL,2 ; no lo es, supuesto un V20 ...
MOV CX,0FFFFh
STI
DB 0F3h,26h,0ACh ; opcode de REPZ LODSB ES:
JCXZ tipo_bus_proc ; ... lo es, calcular bus (V20/V30)
XOR DL,DL ; ya sólo puede ser un 8088/8086
tipo_bus_proc: STD ; transferencias hacia arriba
LEA DI,tipo_bus_dest
MOV AL,BYTE PTR DS:tipo_bus_byte ; opcode de STI
MOV CX,3
CLI
REP STOSB ; transferir tres bytes
CLD
NOP ; el INC CX (1 byte) será machacado
NOP ; con STOSB pero aún se ejecutará
NOP ; en un 8086/80186/V30 (y no en un
INC CX ; 8088/80188/V20) porque está en la
tipo_bus_byte: STI ; cola de lectura adelantada.
tipo_bus_dest: STI
JCXZ cpu_hallada ; el bus ya era supuesto de 8 bits
INC DL ; resulta que es de 16
cpu_hallada: MOV AL,DL
XOR AH,AH
POP SI
POP DI
POP DX
POP CX
POP ES
POP DS
POPF
RET ; AX = CPU: 0/1-8088/86, 2/3-NEC V20/V30
procesador? ENDP ; 4/5-80188/186, 6-286, 7-386, 8-486
print PROC
PUSH AX
PUSH BX
PUSH CX
MOV AH,9
INT 21h
POP CX
POP BX
POP AX
RET
print ENDP
cpus_indice DW i88,i86,v20,v30,i188,i186,i286,i386,i486
i88 DB "Intel 8088 $"
i86 DB "Intel 8086 $"
v20 DB " NEC V20 $"
v30 DB " NEC V30 $"
i188 DB "Intel 80188$"
i186 DB "Intel 80186$"
i286 DB "Intel 80286$"
i386 DB "Intel 80386$"
i486 DB "Intel 80486$"
apuntador_txt DB " <---$"
texto_ini LABEL BYTE
DB 13,10,"CPU Test v2.2 "
DB "(c) Septiembre 1992 Ciriaco García de Celis."
DB 13,10," El microprocesador de este "
DB "equipo es compatible:",10
separador_txt DB 13,10,9,9,9,"$"
texto_fin DB 13,10,"$"
cpu ENDS
END inicio