Глава 23. Тестирование оборудования.

Доверяй, но проверяй.

Русская пословица.

К проблеме тестирования оборудования я неоднократно обращался в предьщущих главах. В данной главе будут рассмотрены некоторые вопросы, не нашедшие своего раскрытия ранее. Надо сказать, что тестирование оборудования является значитель­ной проблемой программирования вообще. Особенно это актуально для такой опера­ционной системы, как MS DOS. Практически не занимаясь управлением внешних ус­тройств, она оставляет это на совести (правильнее сказать на компетентности) про­граммистов. Особенно большие проблемы возникают с графическими устройствами. Я думаю, что многие читатели сталкивались с проблемой, когда игровые программы по непонятным причинам отказывались работать с некоторыми графическими систе­мами. Иная ситуация с операционной системой Windows. Она берет на себя (в отли­чие от MS DOS) практически все взаимодействие с внешними устройствами, и, для

того чтобы знать о наличии или отсутствии того или иного устройства, необходимо лишь осуществить тот или иной системный вызов.

Глава не претендует на полноту изложения, скорее, это несколько примеров того, как пользовательская программа может взаимодействовать с компьютерным оборудо­ванием.

I. Определение типа микропроцессора.

В главе 4 были приведены некоторые критерии, по которым можно различать мик­ропроцессоры INTEL разных поколений. Здесь приводится программа, позволяющая однозначно определить вид микропроцессора. При написании программы автором были заимствованы отдельные идеи из [15].

модуль   программы TEST

.8086

EXTRN ТО_386:FAR .

PUBLIC TEXT PUBLIC TX_80386

PUBLIC    TX_804 86

PUBLIC

PUBLIC VIRT

DATA   SEGMENT PARA ;блок сообщений

TX_8088     DB   'Это процессор  8088',13,10,'$' ТХ_8086   DB  'Это процессор 8086', 13, 10, ' $ ' TX_NEC20  DB   ' Это процессор NEC20',13, 10, ' $ ' TX_NEC3 0 DB   ' Это процессор NEC30 1 , 13, 10,  ' $ ' ТХ_80188 DB  ' Это процессор 80188', 13 , 10, ' $ '

ТХ_80186 DB 'Это процессор 801861, 13, 10, ' $ * ТХ_8028б DB 'Это процессор 8028б',13,10, ' $ ' ТХ_80386 DB 'Это процессор 80386',13,10, 1 $ ' ТХ_80486 DB 'Это процессор 80486 ', 13,10, ' $ ' ТХ_80586 DB 'Это процессор Pentium',13,10,'$1 VIRT DB 'Виртуальный режим. ', 13,10, '$' DATA ENDS

ST1   SEGMENT   PARA   STACK 'STACK' DW 50 DUP(?)

ST1 ENDS

CODE SEGMENT PARA PUBLIC

ASSUME CS:C0DE,   DS:DATA, SS:ST1

BEGIN:

MOV MOV

PUSH SP

POP AX

CMP

JNZ BELOW_2 8 6

; здесь 286  и выше

MOV

PUSH AX

POPF

PUSHF

POP AX

TEST AX,7000H JNZ    N0_2 8 6 ;28б-й

LEA   DX,TX_8 028 6

CALL FAR PTR TEXT

JMP _END N0_2 8 6 :

JMP TO_386 ;здесь   8086,8088,80186,80188,NEC20,NEC30 BELOW_28 6:

CALL TBUFFER

MOV

MOV   CL,33

MOV

SHL AX,CL

JZ

CMP BP,0

■ JNZ _188

LEA DX,TX 80186

CALL FAR PTR TEXT

JMP SHORT END

188:

LEA DX,TX_80188

CALL FAR PTR TEXT JMP SHORT _END NO_18 6:

MOV

JMP SHORT $+2

DB 0F3H,026H,OACH     ;REP LODSB E: JCXZ NEC /8088/8086

CMP

JNZ _88

LEA

CALL FAR PTR TEXT JMP SHORT END

_88 і

LEA

CALL FAR PTR TEXT JMP SHORT _END

NEC:

cmp

JNZ NEC20 LEA

CALL FAR PTR TEXT JMP SHORT _END

NEC20:

LEA

CALL FAR PTR TEXT

_END:

MOV

INT 21H

процедур

для   тестирования   длины буфера ;в CX - '0,   если буфер составляет б байт TBUFFER  PROC NEAR

PUSH ES

PUSH

STD

PUSH CS POP ES

LEA DI,CS:MET2

MOV AL,BYTE   PTR CS:MET1

MOV CX, 3

CLI

REP STOSB

CLD

NOP

NOP

NOP

INC CX

МЕТ1 : STI MET2: STI

POP DI

POP ES

RETN TBUFFER ENDP TEXT PROC FAR

MOV AH, 9

INT 21H

RETF TEXT ENDP CODE ENDS

END BEGIN

модуль   программы TEST1

.386P

PUBLIC

EXTRN

EXTRN

EXTRN TX_80386:BYTE EXTRN TX_80486:BYTE EXTRN TX_80586:BYTE

CODE1   SEGMENT   PARA USE16

ASSUME CS:CODEl

TO_386:

MOV

TEST AL,1 JZ NOVIRT

LEA DX,VIRT

CALL   FAR PTR TEXT

NO_VIRT:

AND PUSH AX

. POPF CALL M486_386 CMP AL,0

JNZ      _4 8б

LEA DX,TX_80386 CALL   FAR   PTR TEXT JMP _END

_486 :

; здесь 486  или выше

CALL

CMP AL,0

JNZ _PENT

LEA DX,TX_80486

CALL FAR PTR TEXT

JMP _END

_PENT:

;зто Пентиум

LEA DX,TX_80586

CALL FAR PTR TEXT

_END:

MOV AH,4CH

INT 21H

/процедура различает   386-й  от 486-го /проверяется 18-й  бит  в регистре флагов

PROC

CLI

PUSHFD POP ЕАХ

AND      ЕАХ,11111111111110111111111111111111В

PUSH ЕАХ POPFD

PUSHFD

POP ЕАХ

TEST ЕАХ,00000000000001000000000000000000В jnz   NO_4 8 6

OR       ЕАХ,00000000000001000000000000000000В

PUSH ЕАХ

POPFD

PUSHFD

POP ЕАХ

TEST   ЕАХ,00000000000001000000000000000000В

JZ     N0_4 8 6 MOV AL,1 STI

RETN

NO_48 6:

MOV AL,0

STI RETN M4 86_386 ENDP

/процедура,  распознающая Pentium,   основанная на отсутствии ;у него  буфера команд PENT_4 86 PROC MOV AL,1

JMP   $+2       ;сбросить очередь команд MOV byte ptr  $+6,0c3h    ;код C3h <-> RET NOP NO_PENT:

MOV AL,0 ;Здесь процессор 80486

RETN ENDP

CODE1 ENDS

END TO_386

Рис. 23.1. Программа, определяющая тип микропроцессора.

Данная программа состоит издвухмодулей. Это не случайно. Дело втом, что часть команд должна выполняться в режиме 386-го процессора. Они вынесены в модуль TEST1. Программа определяет весь спектр существующих микропроцессоров вплоть до Pentium'a. Отличие Pentium'a от других микропроцессоров семейства Intel заключается в отсутствии у него буфера команд (см. главу 4). Обратите Ваше внимание на то, как стыкуютсядруг с другом модули. Здесь Вам понадобится информация из главы 13.

Далее приводится словесный алгоритм определения типа микропроцессора.

1. Начало: разбиваем все семейство микропроцессоров нато, что ниже 286-го (ниж­нее семейство), и остальные. Дело в том, что, начиная с 286-го микропроцессо­ра, стек начал работать несколько по-иному. Вопрос заключается в том, когда меняется содержимое SP- до команды PUSH или после. Индикатором является команда PUSH SP. У микропроцессоров 286-х и выше содержимое SP меняется после команды PUSH.

2. Рассмотрим теперь «нижнее семейство». Вначале определяется индикатор дли­ны буфера команд: процедура TBUFFERB03BpaniaeT в CL0, если длина буфера команд составляет 6 байт.63 Далее используется особенность работы сдвиговых операций для микропроцессоров 80186/80188. Выделив это подсемейство, мы легко отделяем 186-й от 188-го, т.к. длина буфера 186-го составляет 6 байт.

3. Следующий этап - семейство NEC.64 Оно определяется по особенности работы команды LODSB. Далее NEC30 отличается OTNEC20 опять тем, что длина бу­фера у NEC30 составляет 6 байт.

63 Процедура взята из [15].

В отличие от подсемейства автору приходилось довольно часто сталкиваться с

компьютерами на базе микропроцессоров семейства NEC.

4. Теперь у нас в «нижнем семействе» осталось всего два микропроцессора: 8086 и 8088. И здесь идем по пути сравнения длин буферов команд: у микропроцес­сора 8086 длина составляет 6 байт.

5. Вернемся теперь к остальным микропроцессорам. Процессор 80286 легко оп­ределяем по причинетого, что, хотя унего врегистре флагов и появились, биты 12,13,14 (см. главу 20), в реальном режиме они не устанавливаются.

6. Наличие виртуального режима у микропроцессоров 386-х и выше определяем по наличию нулевого бита в регистра CRO.

7. 486-й процессор отличается от 386-го по наличию 18-гобитав регистре флагов.

8. Наконец Pentium отличается от всех остальных отсутствием у него буфера команд.

II. Определение типа видеосистемы.

В главе 7 (Рис. 7.7) была приведена процедура определения типа видеоадаптера. И

здесь добавить нечего.

III. Определить присутствие сопроцессора.

Программа определения присутствия сопроцессора основана на том факте, что команды сопроцессора при отсутствии такового просто игнорируются. Следователь­но, достаточно выполнить несколько команд сопроцессора и проверить получивший­ся результат. Поскольку, начиная с 486-го микропроцессора, сопроцессор стал его неотъемлемой частью, приведенная ниже программа носит в значительной степени

познавательный характер.

code segment

assume CS:CODE, DS:CODE

ORG 100H

BEGIN:

;готовим данные

MOVTEST1, 7890H

MOVTEST2,0 ;выполнить   команды сопроцессора /поместить в  вершину стека

FILD TEST1 /взять  с  вершины стека

FIST TEST2 ;сравниваем

MOV AX,TEST1

CMP AX,TEST2

JZ YES /сопроцессор отсутствует

LEA DX,MES2

JMP     SHORT _END

YES:присутствует LEA DX,MES1

_END:

MOV АН, 9

INT 21H RET ;данные

TEST1 DW ? TEST2   DW ?

MES1 DB 'Сопроцессор присутствует. ', 13,10, ' $ 1 MES2 DB   'Сопроцессор не обнаружен.', 13,10, '$'

CODE ENDS

END BEGIN

Puc. 23.2. Программа определения присутствия сопроцессора. IV. CMOS-память.

Компьютеры AT имеют питаемые от батарейки часы реального времени (RTC -

Real-Time Clock) и CMOS-память (64 байта). Эта память содержит разнообразную информацию о данном компьютере. Доступ к CMOS-памяти осуществляется через 70Н, 71Н порты. Вначале в порт 70Н помещается адрес ячейки памяти, а затем через порт осуществляется чтение или запись. Ниже дана расшифровка содержимого ячеек, взятыхмноюиз "Электронного справочника программиста".

Адрес

Описание

0

Текущая секунда часов

1

Сигнальная секунда

2

Текущая минута

З

Сигнальная минута

4

Текущий час

5

Сигнальныйчас

6

Текущий день недели (1 - воскресенье)

У

Текущий день месяца

8

Текущий месяц

9

Текущий год (две цифры)

Все порции RTC хранятся в формате BCD как две десятичные цифры; например, 31 хранится как 31 Н.

ОАН    RTC  статус  -  регистр А

7

6-4

3-0

 

с

 

-

стор частоты (установлен в ОНО) аговый разделитель   (установлен в 010)

"работает обновление"  (ГЛР) .

О - можно читать.

RTC статус - регистр Б

7

б

S 4

з

2

І

o

 

 

_1

 

 

 

 

\_летнее время.  О=стандартное время  (уст.  в 0)

-12 или 24-часовой режим. 0=Х2-часовой (уст. в1)

-представление даты.   Х=двоичный, Q-BCD, (уст.вО)

-1=вкл. квадр. волну,  (уст. б- О)

--прерывая, по концу обновления запрет, (уст. в О)

-прер. по сигналу запрещает, (уст. в 0)   INT ХАН

-периодическое прерывание.О запрещает.(уст. в 6)

-флаг "работает обновление" (И1Р) . О - можно читать.

ОСН ЯТС статус - регистр С. Биты статуса прерывания можно только читать. Биты:

0-3 - резерв,

4,5,6 - сигнализируют об окончании прерывания (одного из трех видов, см. При­ложение 9),

7 - указывает на наличие прерывания (1).

Обработчик прерывания должен прочесть этот регистр, иначе следующее преры­вание не будет выработано.

RTC статус - регистр D. получает питание

=0: батарейка села.

байт статуса диагностики POST

$43

_► Бремя корректно   (1:   не 30-е февраля и т.п.)

—t Плохой винчестер.   1:  загрузка ие идет

—» Размер rah невер.   1:   TOST нашла иной размер RAH

—» Запись конфигурации неверна.  1: оборудов.другое

-+ 1:  Контрольная сумма CMOS RAM неверна.

■■■■+ Потеря питания.   1:  батарейка реальных часов кончилась

7

б

0FH байт статуса закрытия

Этот байт считывается после сброса CPU, чтобы определить, вызван ли сброс с целью выйти из защищенного режима работы процессора 80286.

0 = мягкий сброс (CTRL-ALT-DEL) (или неожиданный). Обойти POST

1 = закрытие после определения размера памяти

Глава 23.   Тестирование оборудования

2 = закрытие после выполнения теста памяти

3 = закрытие после ошибки памяти (сбой четности 1 или 2)

4 = закрытие по запросу начального загрузчика

5 - закрытие по FAR JMP (рестарт контроллера прер. и JMP 0:[0467Н]) 6,7,8 = закрытие после прохода теста защищенного режима

9 = закрытие после пересылки блока. См. INT 15Нподф. 87Н

ОАН = закрытие по FAR JMP (немедленный JMP по адресу в 0:[0467Н])

ЮН типы

7-4

3--o

первое устройство =

второе устройство 0001 = 0010

ОН = не уст. Ш = ЗбОК = 2Н = 1.2Н

резерв

12Н  тип винчестера   (для устройств С:  и D:,  если от 1 до 14)

7-4

з-o

L_,.первый винчестер   (устр.   С:)      0000 =отсут. —■-*   второй винчестер  (устр.  D:)    иначе = Н> типа (ниже)

1111 =исп.адр.19Н/1АН

См. Типы винчестеров AT BIOS об устройствах, поддерживаемых BIOS.

резерв

Байт оборудования

7-6

6-4

3-2

1

0

хотябы   один флоппи-дисковод устан. ' 1 =  80287  сопроцессор установлен ■ первичный дисплей 00 = нет или _ЕОА_ 01 = 40-кол ССА

10 = 80-кол ССА

11 = ТТЬ НСетОСНБЮНЕ 11 = ТТЬ НОИОСНИОИЕ

флоппи-дисководов без 1  (00=1, 01=2, 10=3,

15Н основная память (младш) --> 0100Н=256К, 0200Н=512К, 0280Н=640К основная память (старш)

17Н расширенная память за 1М (младш)->(в К-байтах. 0-ЗСООН)

18Нрасширеннаяпамять(старш)-> См. INT ІЗНподф. 88Н

19Ндиск 0 (устр. С:)тип винчестера, если (CMOS ADDR 12H&OFH) = OFH 1 АНдиск 1 (ycrp.D:) тип винчестера, если (CMOS ADDR 12Н & FOH) = FOH резерв

2EH контр, сумма по адресам CMOS 10H..2DH (старший байт)

2FH (младший байт)

ЗОН расширенная память за 1М (младш) —> (в К-байтах. 0-ЗСООН)

ЗШрасширенная память(старш)-> См. INT 15Н подф. 88Н

32Н столетие в коде BCD (например, 19Н)

ЗЗН смешанная информация. Бит7=1ВМ 128Кнеобязательная плата памяти Бит 6=используется утилитой "SETUP" 34H-3FH резерв.

Ниже мы представляем программу проверки контрольной суммы CMOS. В ста­рых справочниках говорилось, что контрольная сумма берется с ячеек 10Н-20Н. В новых компьютерах берутся ячейки 10H-2DH. В старых компьютерахячейки 21Н-2DH не использовались и имели нулевое значение. По этой причине программа на Рис. 23.3 должна давать правильный результат и на старых компьютерах AT.

CODE SEGMENT

ASSUME CS:CODE, DS:CODE

ORG 100H

BEGIN:

/поместить контрольную сумму в регистр DX MOV AL,2EH OUT 70H,AL JMP $+2 IN AL,71H MOV DH, AL MOV AL,2FH OUT 70H,AL JMP $+2 IN AL,71H MOV DL, AL

MOV SI,DX    ;b SI контрольная сумма ;сосчитать

MOV CX,30 ;количество ячеек MOV BL,10H   /начальный адрес

XOR DX,DX     /будет накапливаться сумма XOR АН,АН

LOO:

MOV

OUT 70H,AL JMP $+2 IN AL,71H ADD DX,AX INC BL LOOP LOO ;сравниваем CMP

JZ YES LEA DX,MES2

JMP   SHORT END

YES:

lea dx,mes1

_END:

mov   AH, 9 int 21h ret /данные

MES1 DB 'Контрольная сумма CMOS в порядке.', 13,10, '$ •

MES2 DB 'Обнаружено несовпадение контрольной суммы. ', 13,10,'$'

CODE ENDS

end begin

Рис. 23.3. Проверка контрольной суммы CMOS.

V. Тест клавиатуры.

Ниже приводится программа, тестирующая клавиатуру. Программа полностью основана на справочном материале, содержащемся в Приложении 9. Предлагаемый тест нельзя назвать всеобъемлющим. Читатель легко может развить данную програм­му, используя данные Приложения 9. В этом приложении Вы найдете еще одну про­грамму управления клавиатурой непосредственно через ее регистры.

code segment

assume CS:CODE, DS:CODE

org 100h

BEGIN:

CLI

когда можно  послать команду CALL WAIT_OUT_BUF    /свободен выходной буфер? CALL WAIT_IN_BUF      /свободен входной буфер? /команда  получения  управляющего байта MOV AL,20H OUT 64H,AL

CALL WAIT_IN_BUF    /команда принята? CALL WAIT_OUT /управляющий байт в буфере?

. IN     AL,60Н

/запомнить   исходное   состояние  управляющего байта

MOV _AL,AL j. **********************

/ждем,   когда можно  послать команду

CALL WAIT_OUT_BUF     /свободен выходной буфер?

CALL WAIT_IN_BUF       /свободен входной  буфер? . /внутренний тест контроллера

MOV    AL,ОААН

OUT 64H,AL

504

ASSEMBLER..   Учебный курс

CALL WAIT_OUT ;ответ получен?

IN AL,60H

MOV _TEST_K,AL /восстановить управляющий байт CALL WAIT_IN_BUF MOV    AL,60H

OUT     64H,AL      /команда отправки управляющего байта CALL WAIT_IN_BUF MOV AL,_AL

OUT     60H,AL      /отправляем управляющий байт

CMP _TEST_K,55H

JNZ ERR1 /команда клавиатуры 'эхо'

CALL WAIT_IN_BUF

MOV    AL,OEEH

OUT 60H,AL

CALL WAITjDUT

IN      AL,60H

CMP    AL,OEEH

JNZ ERR2 /внутренний тест  клавиатуры (сброс)

CALL WAIT_IN_BUF

MOV    AL,OFFH

OUT ' 60H,AL

CALL WAIT_OUT

IN AL,60H

cmp   AL,OFAH    /команда сброса получена?

JNZ ERR2 CALL WAIT_OUT IN AL,60H

CMP    AL,0AAH     /тест прошел успешно? JNZ ERR2 JMP _END

ERR1:

STI

POP AX

LEA DX,MES_1

MOV AH, 9

int 21h MOV АН,4CH MOV AL,2

INT 21H

ERR2 ;

STI

POP AX

LEA  DX,MES 2

Глава 2З. Тестирование оборудования

MOV

INT 21H

MOV АН,4CH MOV AL, 3

INT 21H

ERR:

STI

POP AX

LEA DX,MES_0 MOV AH, 9 ,INT 21H MOV АН,4CH MOV AL, 1

INT 21H

_END:

STI

LEA DX,MES

MOV AH, 9

INT 21H

MOV AH,4CH

MOVAL,0

INT 21H

;ждать,   когда освободится входной буфер WAIT_IN_BUF PROC XOR CX,CX

ТІ:

IN AL,64H TEST AL,2

LOOPNZ Tl JNZ ERR RETN

WAIT_IN_BUF ENDP

;ждать,   когда освободится выходной буфер WAIT_OUT_BUF PROC XOR CX,CX

T2 :

IN

TEST AL,1

LOOPNZ T2 JNZ ERR RETN

WAIT_OUT_BUF ENDP

;ждать,  когда заполнится выходной буфер

WAIT_OUT PROC

ТЗ:

IN

TEST AL,1

АББЕМВЬЕК.Учебный курс

JZ ТЗ

RETN

WAITJDUT endp _al    db ? _TEST_K  DB ?

MES_0     DB клавиатуры во время

MES_1     DB контроллера  клавиатуры не

DB клавиатуры не

DB клавиатуры прошел

CODE ENDS

END BEGIN

Рис. 23,4.Программа тестирования клавиатуры.

VI. Часы реального времени и системный таймер.

Во время запуска MS DOS происходит установка системного таймера по часам реального времени (на компьютерах XT часов реального времени не было). В даль­нейшем системные часы ориентированы на системный таймер, который увеличивает­ся по прерыванию 08Н. В идеале системные часы и часы реального времени должны идти одинаково. Однако это невсегдатак. Ниже я привожу программу, позволяющую сделать простейшее сравнение того, как идут эти часы. Сравнение производится визу­ально на экране. Программа может работать сколь угодно долго, то есть сравнение может быть произведено за достаточно длинный промежуток.

.286

CODE SEGMENT

assume CS:CODE,   DS:CODE

org 100H

BEGIN:

; ES -  для  вывода на экран

MOV

mov ES,AX

экран

mov

xor   SI,SI

_CLS:

mov

add  SI,2

LOOP _CLS

mov CX,23

надпись ТЕХТ1 lea SI,TEXT1 mov DI,2000-80

__ТЕХ1:

MOV AL, [SI] MOV ES: [DI] , AL INC SI ADD DI, 2 LOOP _TEX1 MOVCX,23 ' LEA SI,TEXT2 MOVDI,2320-80

_TEX2:

;вывести надпись ТЕХТ2 MOV AL, [SI] MOVES: [DI],AL INC SI ADD DI, 2 LOOP _TEX2

LOOP1:

/читать показание счетчика MOV АН, 0

INT 1AH

/преобразовать в  показание  системных часов

CALL _COUNT

показание  системных часов

MOV DI,2320

CALL PRINT /читать показания  встроенных часов

MOV АН,2

INT 1AH

/преобразовать формат BCD ■ CALL _BCD

показание   встроенных часов MOV DI,2000

CALL PRINT

/проверить,   не нажата ли клавиша

MOV АН, 1

INT 16H

JZ  LOOP1 ' ;очистить  буфер клавиатуры

MOV АН, б

MOV DL,OFFH

INT 21H ; выйти в ОС

RETN ■

ASSEMBLER. Учсбныйкурс

;процедура печати времени PRINT PROC

MOV СХ,8

LEA SI,SHABL

LOOl :

MOV AL,[SI] MOV  ES:[DI],AL

MOV BYTE   PTR ES: [DI]+1, 12

INC SI ADD DI,2 LOOP LO01 RETN

PRINT ENDP

/преобразование числа  в  BCD-формате  в шаблон для печати /времени по  часам реального времени _BCD PROC / часы

MOV AL,СН

SHR AL,4

ADD AL,4 8

AND CH,00001111b

CMP CH, 10

jb    _0K1■

ADD al,1

SUB CH,10

_0K1 :

ADD CH,4 8

MOV BYTE   PTR  SHABL, AL MOV BYTE   PTR SHABL+1,CH /минуты

MOV

SHR AL,4 ADD AL,4 8

AND CL,00001111B CMP CL,10 JB _ok2 ADD AL,1 SUB CL,10

_OK2 :

ADD

MOV  BYTE   PTR SHABL+3,AL MOV  BYTE   PTR SHABL+4,CL /секунды

MOV

SHR AL,4

ADD AL,4 8

AND DH,00001111В

CMP DH,10

JB _ok3 . ADD   AL, 1 SUB DH,10

_ok3 :

ADD DH,48

MOV BYTE PTR SHABL+6, AL MOV BYTE   PTR  SHABL+7, DH

RETN _BCD ENDP

/преобразование показателя  счетчика  в шаблон для ;печати времени по  системным часам _COUNT PROC

MOV AX,DX

MOV DX,CX

MOV CX,65520

DIV CX /часы в AX

PUSH DX

MOV CL,10

DIV CL

ADD AL,48

ADD AH,48

MOV BYTE   PTR SHABL,AL MOV BYTE   PTR  SHABL+1, AH POP AX ' XOR   DX, DX MOV CX,1092

DIV CX ; минуты в AX

PUSH DX

MOV CL,10

DIV CL ADD AL,48 ADD AH,48

MOV BYTE   PTR SHABL+3,AL MOV BYTE   PTR  SHABL+4, AH POP AX XOR DX,DX MOV CX,18

DIV CX ;секунды

MOV CL,10

DIV CL ADD AL,48

ADD

MOV BYTE PTR SHABL+6, AL

MOV BYTE PTR  SHABL+7, AH RETN

ENDP ;шаблон

SHABL DB

TEXT1 DB   'Часы реального времени:' TEXT2   DB   'Системные часы:

CODE ENDS

END BEGIN

Рис. 23.5. Сравнение хода часов реального времени и системных часов.

Приведенная выше программа основывается на результатах вызова прерывания

1 АН (см. Приложение В). Советую Вам разобраться в процедурах преобразования BCD-формата и преобразования счетчика системного таймера.