Ошибка в процессоре Pentium
В листинге 10.2 мы привели исходный текст программы PENTERR, с помощью которой можно обнаружить известную ошибку в арифметическом сопроцессоре, встроенном в процессор Pentium. Эта ошибка приводит к снижению точности результата при делении некоторых комбинаций чисел.
В нашем случае мы проверяем результат вычислений по следующей формуле:
(4195835 / 3145727) * 3145727
Если ошибки нет, в результате вычислений должно получиться значение 4195835. При наличии ошибки значение результата будет меньше этого числа на 256.
Листинг 10.2. Файл penterr\penterr.asm
; =====================================================
; Проверка наличия ошибки в сопроцессоре,
; встроенном в процессор Pentium
;
; (C) A. Frolov, 1997
;
; E-mail: frolov@glas.apc.org
; WWW: http://www.glasnet.ru/~frolov
; or
; http://www.dials.ccas.ru/frolov
; =====================================================
.model small
.STACK 100h
.DATA
.286
x dd 4195835.0
y dd 3145727.0
z dd ?
BugMsg db 13,10,"Pentium NPU bug detected!", "$"
OkMsg db 13,10,"Your Pentium NPU is OK", "$"
.CODE
begin:
mov ax, DGROUP
mov ds, ax
; Записываем в стек численных регистров
; значение x
fld x
; Делим содержимое верхушки стека
; на константу y
fdiv y
; Умножаем содержимое верхушки стека
; на эту же константу
fmul y
; В результате при отсутствии ошибки мы должны
; получить результат, равный x
fcom x
; Сохраняем регистр состояния сопроцессора в AX
fstsw ax
; Переписываем AH в регистр флагов
sahf
; Проверяем равенство нулю
jnz bug
; Ошибки нет
mov ah, 9
mov dx, offset OkMsg
int 21h
jmp next
; Обнаружена ошибка
bug:
mov ah, 9
mov dx, offset BugMsg
int 21h
; Завершаем работу программы и
; возвращаем управление операционной системе
next:
mov ax, 4C00h
int 21h
END begin