Добавил:
kostikboritski@gmail.com Выполнение курсовых, РГР технических предметов Механического факультета. Так же чертежи по инженерной графике для МФ, УПП. Писать на почту. Дипломы по кафедре Вагоны Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

литература / Пухальский Проектирование микропроцессорных систем 2001

.pdf
Скачиваний:
333
Добавлен:
12.11.2017
Размер:
21.12 Mб
Скачать

390

Глава 4. Микропроцессоры 8086/8088 и сопроцессор 8087

Команды CM PS src, dst, CMPSB и CM PSW . Эти команды выполняют сравнение цепочек

(строк) байт или слов:

 

 

Af(DS:SI) - Af(ES:DI),

SI <— SI + m, DI <- DI + m, если DF = 0;

 

M(DS:SI) - M(ES:DI),

SI <— SI - m, DI <- DI - m, если DF = 1,

где m = 1

для байт и m = 2 для слов (операнды не изменяются, а устанавливаются лишь флаги

в соответствии с результатом сравнения).

Выполняются команды за 22 такта (без повторения) и 9 + 22/гер тактов (с повторением), где 22/гер означает 22 х СХ тактов.

Задача 31. Найти адреса первых от начала не совпадающих символов в двух цепочках strl и str2 длиною 32 байта или слова. Решение:

CLD

LEA SI, strl LEA DI, str2 MOV CX, 32

REPE CMPS strl, str2

JE Ll

DEC SI

DEC DI

Ll:

DF 0 — сравнение цепочек от начала к концу SI <— начальный адрес строки (цепочки) strl

DI <— начальный адрес строки str2 СХ <— 32d — число символов в строке

M(DS:SI) - M(ES:DI), SI <- SI + m, DI <- DI + m , CX <- CX - 1

Переход на метку L l, если все символы совпали

SI <— SI —1 — адрес несовпадающего символа в строке strl (для байт) DI <— DI - 1 — адрес несовпадающего символа в строке strl (для байт) Для слов декремент регистров следует сделать два раза

Задача 32. Найти адреса первых от конца совпадающих символов в двух цепочках strl и str2 длиною 32 байта или слова. Решение:

STD

 

 

; DF <—1 — сравнение цепочек от конца к началу

LEA

SI, strl

+31 ; SI <— конечный адрес строки (цепочки) strl

LEA

DI, str2 + 31 ; DI конечный адрес строки str2

MOV

CX, 32

 

; CX <— 32d — число символов в строке

REPNE CMPS

strl, sir2

; M(DS:SI) - M(ES.DI), SI <- SI + m, DI <- DI + m , CX <- CX - 1

JNE

L l

; Переход на метку L l, если все символы не совпали

INC

SI

; SI

SI + 1 — адрес совпадающего символа в цепочке strl (для байт)

INC

DI

; DI

DI + 1 — адрес совпадающего символа в цепочке strl (для байт)

 

 

; Для слов инкремент регистров следует сделать два раза

L1:

 

 

 

Команды SCAS dst, SCASB и SCASW. Данные команды выполняют сканирование (про­ смотр) цепочки (строки) байт или слов:

AL/AX - A/(ES:DI),

DI

DI + т (т = 1

для байт, т = 2

для слов), если DF = 0;

AL/AX - M(ES:DI),

DI

DI - т (т = 1 для байт, т = 2

для слов), если DF = 1,

т. е. производится сравнение содержимого аккумулятора AL или АХ с байтом или словом в памяти по адресу ES:DI (сами операнды не изменяются, а устанавливаются лишь флаги в со­ ответствии с результатом сравнения). Эти команды используются в тех случаях, когда в цепоч­ ке необходимо найти заданный символ.

Выполняются команды за 15 тактов (без повторения) и 9 + 15/гер тактов (с повторением), где 15/гер означает 15 х СХ тактов.

4.3. Система команд МП 8086/8088

391

Задача 33. Найти адрес первого от начала символа

в цепочке string длиною 32 байта.

Решение:

CLD

MOV AL, *&’ LEA DI, string MOV CX, 32

REPNE SCAS string

JNE LI

DEC DI

DF <—0 — сканирование цепочки от начала к концу

AL <— 26h — А5С//-код символа & DI <— начальный адрес строки string

СХ

32d — число символов в строке

; AL - /W(ES:DI), DI

DI + 1, CX <— CX - 1

Переход на метку LI, если символ не найден

DI

DI - 1 — адрес символа ‘&’ в цепочке string

L1:

Команды LODS src, LODSB и LODSW. Эти команды выполняют пересылку цепочек (строк) байт или слов в аккумулятор:

AL/AX <- M(DS:SI), SI = SI + т, если DF = 0;

AL/AX <- M(DS:SI), SI = SI - m, если DF = 1,

где m = 1 для байт и m - 2 для слов, т. е. производится пересылка в аккумулятор AL или АХ байта или слова из памяти с адресом DS:SI. Хотя и разрешается использовать эту команду с префиксом повторения, этого почти никогда не делается из-за отсутствия полезного результа­ та (в регистр AL или АХ при каждом повторении команды LODS загружается новое значение байта или слова с потерей предыдущего значения).

Выполняются команды за 12 тактов (без повторения) и 9 + 13/гер тактов (с повторением), где 13/гер означает 13 х СХ тактов.

Команды STOS dst, STOSB и STOSW. Эти команды выполняют пересылку цепочек (строк) байт или слов:

Af(ES:DI) <- AL/AX, DI = DI + m, если DF = 0;

M(ES:DI) 4- AL/AX, DI = DI - m, если DF = 1,

где m - 1 для байт и m = 2 для слов, т. е. производится пересылка из аккумулятора AL или АХ байта или слова в память по адресу DS:SI. Эти команды полезны в тех случаях, когда некото­ рую область памяти необходимо заполнить заданным символом (инициализация блока памяти).

Выполняются команды за 11 тактов (без повторения) и 9 + 10/гер тактов (с повторением), где 10/гер означает 10 х СХ тактов.

Задача 34. Заполнить блок памяти string длиною 32 слова символами ‘& $ \ Решение:

CLD

 

; DF <—0 — сканирование цепочки от начала к концу

MOV

АХ, *&$’

; АХ <— 2624h, где 26h и 24h — ASCII-коды символов & и $

LEA

DI, string

; DI <— начальный адрес строки string

MOV

СХ, 32

; СХ <■— 32d — число слов в строке

REP STOS string

; M(ES:DI) <— АХ, DI <— DI + 2, СХ <— СХ - 1

Все примитивы производят над элементами цепочек только “пассивные” действия — не преобразуют сами элементы, что требуется, например, в редакторах текстов. Совместное ис­ пользование примитивов LODS и STOS позволяет эффективно производить и преобразование элементов цепочек. Префиксы повторения при этом использовать нельзя — для организации цикла наиболее подходит команда LOOP.

392

Глава 4. Микропроцессоры 8086/8088 и сопроцессор 8087

Задача 35. Написать программу изменения в цепочке string длиною 32 байта прописных латинских букв на строчные. Решение:

41 h = 0100 0001... 5Ah = 0101 1010 — Л5С//-коды прописных латинских букв от А до Z,

61/г = 0110 0001 ... 7Ah = 0111 1010 — А5С//-КОДЫ строчных латинских букв от а до г,

т. е. во всех элементах цепочки требуется установить в 1 разряд 5, что можно выполнить с по­ мощью команды OR AL, 20h (20h = 0010 0000). На основании этого программа будет иметь вид:

CLD

SI, string

LEA

MOV

DI, SI

MOV

CX, 32

LODSB

AL, 20h

OR

STOSB

 

LOOP

Ll

DF <—0 — преобразование цепочки от начала к концу SI <— начальный адрес строки string

DI <— SI

СХ <— 32d — число циклов

AL <- M(DS:SI), SI <— SI + 1

AL <— AL v 20h (20h = 0010 0000) M(ES:DI) AL v 20h, DI <- DI + 1 CX <—CX - 1 и переход, если CX Ф0

5. Команды передачи управления

Некоторые команды передачи управления требуют временного запоминания информации, и затем считывания ее в обратном порядке. Эта задача решается посредством реализации в МП-системах стека, представляющего собой память типа LIFO (last-in, first-out— последним вошел, первым вышел). Такая память называется иначе стеком включения/извлечения. Наибо­ лее важное применение стека связано с процедурами (подпрограммами) и программными и аппаратными прерываниями, требующими автоматического сохранения адресов возврата. Кро­ ме этого стек используется и для временного запоминания данных (команды PUSH — включе­ ние в стек, POP — извлечение из стека).

Для неявной адресации стека используется специальный регистр SP (Stack Pointer) — ука­ затель стека. При включении {push) данных в стек производится автоматический декремент указателя стека SP, а при извлечении (pop) — инкремент. Адрес последнего включенного в стек элемента называется вершиной стека TOS (Top o f Stack).

Команды PUSH src 16 и PO P dstU, PUSHF и POPF. Эти команды относятся к группе команд передачи данных, но они тесно связаны по применению и принципу выполнения опера­ ций с некоторыми командами передачи управления — выполняют операции включения и из­ влечения данных из стека. Стек оперирует только словами и в командах нельзя использовать непосредственные операнды, но все остальные режимы адресации в командах PUSH и POP разрешены. Данные команды являются единственными, кроме команды MOV, в которых до­ пускается задавать сегментный регистр как операнд. Однако в команде POP регистр CS указы­ вать нельзя. Если операнды лгс16 и dst16 находятся в памяти, то команды PUSH и POP выпол­ няют операцию пересылки типа память-память подобно примитиву MOVS.

При выполнении команд PUSH и POP производятся действия:

SP SP - 2, а затем M(SP) <— srcl6, dstl6 <- M(SP), а затем S P < -S P + 2

соответственно. Это же справедливо и для команд PUSHF и POPF, только src 16 = PSW и dstl6 = PSW (Program Status Word — регистр признаков). После одинакового числа включений

4.3. Система команд МП 8086/8088

393

и извлечений вершина стека TOS оказывается в первоначальном положении. Следует соблю­ дать правило: нельзя извлекать из стека какие-либо данные, не включив их сначала в стек. И всегда необходимо помнить о “тайном” смысле терминов “включение” (в стек) и “извлече­ ние” (из стека), подразумевающих автоматическое изменение содержимого указателя стека SP (включение и извлечение — это не то же самое, что запись и чтение данных из памяти).

Физический адрес стека определяется содержимым пар регистров SS:SP или SS:BP, при­ чем SP служит неявным указателем стека для всех операций включения и извлечения, a SS — сегментным регистром стека. Регистр ВР используется, главным образом, для произвольных обращений к стеку. Содержимое SS является самым младшим адресом (границей) области сте­ ка и называется базой стека. Первоначальное значение указателя стека SP, устанавливаемое при инициализации, является наибольшим смещением, которого может достигать стек. Это значение определяет максимальное число слов, которое может быть включено в стек (мини­ мальное значение SP = 0). Местоположение стека задается операционной системой или пользо­ вательской программой.

Временное сохранение операндов в стеке эффективнее использования для этих целей па­ мяти в области сегмента данных: команды PUSH и POP короче других команд и не нужно зада­ вать адрес памяти в явном виде (инкремент и декремент SP производится автоматически).

Команда PUSH выполняется за 11 тактов (reg), 10 тактов (seg) и 16 + еа тактов (М), ко­ манда POP — за 8 тактов (reg и seg SS, DS, ES) и 17 + еа тактов (М), команда PUSHF — за 10 тактов, команда POPF — за 8 тактов.

Команды CALL target и RET. Основным назначением стека является автоматическое запоминание адресов возврата из процедур (подпрограмм), вызываемых командами CALL tar­ get и INT type. Адрес возврата — это находящийся в указателе инструкции IP или в регистрах CS.IP адрес команды, следующей за командой вызова процедуры. Процедуры всегда должны заканчиваться командой возврата RET, автоматически извлекающей из стека адрес возврата и загружающей его в указатель инструкции IP или в регистры CS.IP.

Команда CALL предназначена для внутрисегментного и межсегментного вызова процедур proc (procedure — процедура, подпрограмма), которые могут находиться как внутри текущего сегмента кода (пеаг-ргос — внутрисегментный вызов), так и вне него (far-proc — межсегмент­ ный вызов):

SP <— SP -

2, М(SP)

<— IP, IP

target (near);

 

SP <— SP -

2, M(SP)

CS, SP <— SP - 2, M(SP) 4- IP, IP <h- target1; CS

target2 (far),

где target — одно или два слова адреса передачи управления. Режимы адресации (способы за­ дания адреса target) команд CALL такие же, что и для команд JMP (см. § 4.2, рис. 4.23) — нет только короткого (short) перехода (вызова). Вызов может быть прямым или косвенным, внут­ рисегментным или межсегментным. Команд условных вызовов процедур нет.

Соответственно вызывающим процедуры командам CALL имеются команды RET, выпол­ няющие внутрисегментные и межсегментные возвраты. Команды RET выполняют операции со стеком в обратном направлении:

IP <r~ М(SP), SP <— SP + 2 (near-return)',

IP <- M(SP), SP <— SP + 2, CS <- M(SP), SP <— SP + 2 (far-return).

В команде RET может быть задан непосредственный операнд im16, если через стек в вы­ званную процедуру передавались необходимые ей данные (параметры). В этом случае после извлечения из стека адреса возврата выполняется операция SP + iml6, что соответствует удале­

394 Глава 4. Микропроцессоры 8086/8088 и сопроцессор 8087

нию из стека отработавших параметров (модифицируется вершина стека для обхода этих пара­ метров). Значение im\6 должно быть равно числу слов данных, включенных в стек командами PUSH, перед вызовом процедуры, которой эти данные необходимы. Вызванная процедура по­ лучает доступ к параметрам, адресуя область памяти стека содержимым пары регистров SS:BP, не извлекая их из стека командами POP.

В виде процедур обычно оформляются большие часто повторяющиеся программные фрагменты — в памяти нужно хранить только одну копию процедуры, а вызываться она может много раз из разных мест программы. Процедуры обеспечивают основное средство разделения кода программы на модули, которые можно легко по отдельности разрабатывать, тестировать и документировать. Процедуры можно хранить в библиотеках и использовать многими програм­ мами.

Команда CALL выполняется за 19 тактов (внутрисегментный прямой вызов), 16 тактов (внутрисегментный косвенный вызов через регистр), 21 + еа тактов (внутрисегментный кос­ венный вызов через память), 28 тактов (межсегментный прямой вызов) и 37 + еа тактов (межсегментный косвенный вызов).

Команда RET выполняется за 8 тактов (внутрисегментный возврат), 12 тактов (внутрисег­ ментный возврат с непосредственным операндом), 18 тактов (межсегментный возврат) и 17 тактов (межсегментный возврат с непосредственным операндом).

Пример 19. Передача управления при выполнении одноуровневых процедур:

CALL

proc_ 1

; —

MOV

DL, 75

; <-

proc_ 1 PUSH

AX

Начало процедуры proc_ 1

PUSH

BX

Сохранение содержимого регистров АХ, ВХ и СХ

PUSH

CX

POP

CX

Восстановление содержимого регистров АХ, ВХ и СХ

POP

BX

 

POP

AX

Конец процедуры proc_ 1

RET

 

Содержимое тех регистров, которые использует процедура, будет модифицировано, а зна­ чит необходимо запомнить содержимое этих регистров до его изменения, а перед самым выхо­ дом из процедуры восстановить. Для этого используются команды PUSH и POP. Содержимое стека извлекается из него и загружается в регистры МП в порядке, обратном тому, в каком они включались в стек при выполнении программы.

Если процедура обращалась к стеку (выполняла команды PUSH и POP), то указатель стека SP должен быть возвращен на прежнее значение и действия со стеком не должны были разру­ шить адрес возврата. При работе с процедурами программист должен внимательно следить за правильным использованием стека, в противном случае возможны возвраты из процедур по бессмысленным адресам.

Процедуры могут иметь любое число уровней вложенности, от числа которых зависит, в частности, минимальный размер стека. Размер стека устанавливается программистом, исходя из потребностей разрабатываемой программы.

Пример 20. Передача управления при выполнении двухуровневых процедур:

 

 

 

4.3. Система команд МП 8086/8088

395

 

CALL ргос_ 1

— ©

 

 

 

SUB

DX, DI

«-

 

 

proc_1

PUSH

AX

<r-

Начало процедуры proc_1 первого уровня

 

 

CALL proc_2

— ©

 

 

 

CMP

SI, BX

<-

 

 

 

RET

 

 

© Конец процедуры первого уровня

 

pro cj.

PUSH AX

t—

Начало процедуры proc_2 второго уровня

 

 

RET

 

 

Конец процедуры второго уровня

 

Вэтом примере пояснена последовательность передач управления при выполнении двух­ уровневой процедуры (цифрами ©, ©, ® и © помечен порядок передачи управления).

Взадаче 36 приведен пример оформления на языке ассемблера процедуры CALL c_intr near. Конечно, вводить в программу такую процедуру (содержит всего две команды и исполь­ зуется только один раз) бессмысленно — число команд не сократилось, а увеличилось. Задача 36 предназначена в основном для демонстрации манипуляций с векторами прерываний команд

INT type.

Задача 36. Написать программу вывода на экран дисплея собственного сообщения при возникновении ошибки деления с последующим восстановлением системного вектора преры­ вания INT 0. Решение:

s_seg

 

segment page STACK ; Сегмент стека

s_seg

 

dw

8 dup (0E291A, 0ААА5/г, 5320/г, 2150h) ; Стек SP! — ASCII символы

 

ends

; Конец сегмента стека

d_seg

 

segment

; Сегмент данных

Message

db

10, 10, ‘ Чтоб в арифметике упрочиться,’, 13, 10

 

 

db

‘ О-о-о, Юный Неофит!’, 13, 10

 

 

db

‘ Пиши не так, как хочется,’, 13, 10

 

 

db

‘ А как Zero велит!’, 10, 10, ‘(нажмите любую клавишу)’, *$’

; Управляющие ASCH-KOjxbi:

;

13d = OD/г — возврат каретки (сдвиг курсора в левую позицию экрана)

;10d = ОА/г — перевод строки (сдвиг курсора вниз на одну позицию)

;$ — задание конца строки, выводимой на дисплей

d_seg

ends

 

 

; Конец сегмента данных

c_seg

segment

 

 

; Сегмент кода

 

assume CS: c_seg, DS: d_seg, SS: s_seg, ES: d_seg

main

proc

far

 

; Начало процедуры main

 

push

ds

; Запись в стек начального адреса PSP (Program Segment Prefics)

 

sub

ax, ax

;

и 0000h (для возврата в DOS)

 

push

ax

 

 

 

mov

ax, djseg

 

 

 

mov

ds, ax

; Инициализация сегментного регистра DS

 

mov

es, ax

; ES = DS

396

Глава 4. Микропроцессоры 8086/8088 и сопроцессор 8087

; Получение системного вектора прерывания CSc:IPc для INT О

CALL

c_intr

; АН <— 35ft — номер функции, AL <— type = 00

; Исходное значение указателя стека SP = SP0

PUSH

ВХ

; SP

SP - 2, M(SP0 -2)< IPc (сохранение в стеке CSc:IPc)

PUSH

ES

; SP <- SP - 2, M(SP0 - 4) CSc

; Замена системного вектора прерывания пользовательским CSuilPy

PUSH

DS

 

 

LEA

DX, zero

 

 

MOV

AX, c_seg

 

 

MOV

DS, AX

 

25ft — номер функции, AL <— type = 00

MOV

AX, 2500ft

; AH

INT

21ft

; M(0000) <- IPu = offset zero, M(0002) <- CSu = c_seg

POP

DS

; DS <- M(SP0 - 6), SP <- SP + 2

;INT 21ft, функция DOS 25ft — установка вектора прерывания

;Деление целых чисел с переполнением (“divide by zero”)

MOV

BL, 0A4/I

; BH <- A4h = 164rf

MOV

AX, 0A400ft

; AX <— A400ft = 41984c?

DIV

BL

; “divide by zero" => системное прерывание INT 0

MOV

AH, 8

 

INT

21ft

; Ожидание нажатия любой клавиши

; INT 21ft, функция DOS 08ft — ввод с клавиатуры символа в ASCII-коде без эха

; Восстановление системного вектора прерывания для INT 0

CLI

 

IF <— 0 — запрет аппаратных прерываний

MOV

SI, DS

 

 

 

 

 

POP

AX

AX

M(SP0 - 4)

= CSc, SP

SP + 2

MOV

DS, AX

DS

CSc

 

 

 

POP

DX

DX 4 - M(SP0 - 2)

= IPC, SP

SP + 2

type = 00

MOV

AX, 2500ft

AH <—25ft — номер функции, AL

INT

21ft

M(0000) 4- IPC, M(0002)

CSc

.

; INT 21/г, функция DOS 25ft — установка (восстановление) вектора прерывания

 

MOV

DS, SI

 

 

 

STI

 

; IF

1 — разрешение аппаратных прерываний

main

RET

 

Конец процедуры main

endp

 

; Подпрограмма для получения системного вектора прерывания

c_intr

proc

near

Начало процедуры c_intr

 

MOV

AX, 3500ft

АН <— 35ft — номер функции, AL <— type = 00

 

INT

21ft

BX <- M(0000) = IPC, ES M(0002) = CSc

;ES.BX = CSc:IPc — адрес подпрограммы INT 0

;INT 21ft, функция DOS 35h — получение вектора прерывания

c_intr

RET

 

; Конец процедуры c_intr

endp

 

; Подпрограмма, вызываемая системным прерыванием INT 0

zero

proc

far

; Начало процедуры прерывания zero

 

POP

АХ

; Изменение адреса возврата на команду, следующую за

 

ADD

АХ, 2

;

командой DIV, вызывающей проблему “divide by zero”

 

 

4.3. Система команд МП 8086/8088

397

PUSH

АХ

 

 

LEA

DX, Message; DX — начальный адрес символьной строки

 

MOV

АН, 9

; Вывод на экран дисплея сообщения Message:

 

INT

21h

; Чтоб в арифметике упрочиться,

 

;О-о-о, Юный Неофит!

;Пиши не так, как хочется,

;А как Zero велит! (нажмите любую клавишу)

;INT 21h, функция DOS 09h — вывод на дисплей А5С//-строки

zero

IRET

 

; Конец процедуры прерывания zero

endp

 

c_seg

ends

 

; Конец сегмента кода

 

end

main

; Конец программы

Команды INT type и IRET. В системе команд имеется три типа команд программного прерывания'. INT 3, INTO (однобайтовые команды) и INT type (двухбайтовые команды), где type = 0 ... 255. Прерывания подразделяются на внутренние, которые вызываются состоянием МП или одной из перечисленных команд, входящих в программу, и внешние — инициируемые сигналом, подаваемым в МП от других компонент системы (обычно запросы прерываний по­ ступают от контроллера прерываний 8259.4 и по входу немаскируемого запроса прерывания ЫМГ). Типичное внутреннее прерывание инициируется, например, при делении числа на нуль, атипичные внешние прерывания — сигналами на входах NMI и INTR микропроцессора. Ко­ манды прерываний по назначению аналогичны командам CALL вызова процедур (подпро­ грамм). Вызываемая командой прерывания подпрограмма называется процедурой прерывания.

Некоторыми видами прерываний управляют флаги IF и TF. Если условия для прерывания удовлетворяются и необходимые флаги установлены, МП завершает текущую команду, а затем реализует последовательность прерывания:

SP <— SP -

2,

M (SP)<-PSW , TF <— 0, IF <— 0,

SP <- SP -

2,

M(SP) <- CS, SP SP - 2, M(SP) IP,

IP <— M(4 x type), CS <— M(4 x type + 2),

где PSW — регистр признаков, TF — флаг трассировки, IF — флаг разрешения прерываний, 4 х type — адрес первого слова вектора прерывания, 4 х type + 2 — адрес второго слова вектора прерывания. Новое содержимое регистров IP и CS определяет начальный адрес выполняемой процедуры прерывания.

Двойное слово, загружаемое в указатель инструкции IP и сегментный регистр кода CS, называется вектором прерывания. Для хранения двойного слова требуются 4 байта, поэтому вектора прерываний могут занимать первые 1024 байта памяти и их нельзя использовать для других целей. Некоторые из 256 типов прерываний резервируются операционной системой и должны инициализироваться после включения компьютера. Пользователи приспосабливают остальные типы прерываний в соответствии со своими требованиями. В задаче 36 было пока­ зано, как можно использовать и системные векторы прерываний для вызова своих процедур обслуживания прерываний.

После обслуживания прерывания возврат в прерванную программу осуществляется ко­ мандой IRET, которая извлекает из стека значения IP, CS и PSW:

IP< -M (SP), SP SP + 2, C S f-M (S P ), SP <— SP + 2, PSW <-M (SP), SP <— SP + 2

в обратном порядке по отношению к их включению в стек.

398

Глава 4. Микропроцессоры 8086/8088 и сопроцессор 8087

 

Команда INT type

 

П ам ять

 

Адрес

 

Назначение

 

INTO

IP

для type 0

00000/г

. Зарезервировано для

 

 

CS

для type

0

 

/

ошибки деления

 

INT 1

IP

для type 1

00004/г

ч Зарезервировано для

 

 

CS

для type 1

 

I

пошагового режима работы

 

INT 2

IP

для type

2

00008h

» Зарезервировано для

 

 

CS

для type

2

 

Г

немаскируемого прерывания

 

INT 3

IP

для type 3

0000С/г

* Зарезервировано для однобайтной

 

 

CS для type

3

 

J

команды прерывания

 

INTO

IP

для type

4

00010h

1 Зарезервировано для команды

 

 

CS для type

4

 

/

прерывания по переполнению

 

INT 5

IP

для type

5

00014/г

 

 

 

 

CS для type

5

 

 

 

 

,

 

.

 

00018/i. . 003F8h

 

 

 

 

 

 

INT 255

IP

для type

255

ООЗБС/г

 

 

 

 

CS для type

255

 

 

Конец таблицы

 

 

 

 

 

00400/г

 

 

Рис. 4.26. Векторная система прерываний

Типы прерываний представлены на рис. 4.26, иллюстрирующем размещение векторов прерываний в памяти. Только первые пять типов определены явно, а остальные отведены для команд программных прерываний (INT type, используемых в программах) или внешних аппа­ ратных прерываний type, поступающих от контроллера прерываний 8259А. Некоторые типы прерываний в персональных компьютерах IBM PC используются операционной системой

MS-DOS (Microsoft Disk Operating System) и базовой системой ввода-вывода BIOS (Basic Input-Output System), обеспечивающей управление периферийным оборудованием компьютера. Например, команда INT 21h вызывает для выполнения функцию MS-DOS, номер которой дол­ жен быть предварительно задан в регистре АН (см. § 4.5), а команда INT 10h — функцию

BIOS.

Прерывание типа 0 вызывается автоматически по ошибке деления — компьютер включает текущее содержимое регистров PSW, CS и IP в стек, загружает регистры IP и CS из содержимо­ го памяти по адресам 00000 и 00002 и продолжает выполнение программы с адреса, опреде­ ляемого новым содержимым регистров IP и CS. Прерывание из-за ошибки деления возникает независимо от состояния флагов IF и TF, когда в командах DIV или IDIV частное превышает диапазон представления чисел.

Прерывание типа 1 обеспечивает пошаговую работу и только им управляет флаг TF. Если значение флага TF - 1, то по окончании следующей команды возникает прерывание, которое вызывает процедуру обработки прерывания, адрес которой определяется содержимым ячеек памяти 00004 ... 00007.

Прерывание типа 2 вызывается независимо от состояния флага IF сигналом, поступающим на вход NMI (Non-maskable Interrupt) микропроцессора.

Остальные типы прерываний вызываются либо командами прерываний, включенными в программу (этими прерываниями флаг IF не управляет), либо внешними прерываниями, за­

4.3. Система команд МП 8086/8088

399

просы которых поступают на вход 1NTR микропроцессора (разрешением и запретом этих пре­ рываний управляет флаг IF).

Команда INT 3 часто применяется при отладке, когда пошаговая работа дает больше ин­ формации, чем требуется. Помещая команды INT 3 в контрольных точках программы (Break­ point interrupt), программист может использовать процедуру прерывания для вывода на экран дисплея или на принтер результата выполнения программы до контрольной точки.

Команда INTO имеет тип 4 и вызывает прерывание, если только значение флага OF = 1. Ее часто помещают сразу после арифметической команды, способной вызвать ошибку переполне­ ния, и при наличии переполнения осуществляется специальная обработка этой ошибки. В отли­ чие от деления на нуль переполнение не вызывает автоматического прерывания — прерывание необходимо явно определять командой INTO.

Команда IRET осуществляет возврат из процедуры прерывания. Она аналогична команде RET, но кроме адреса возврата извлекает из стека исходное содержимое PSW.

Команда INT 3 выполняется за 52 такта, команда INTO — за 53 такта (OF = 1) и за 4 такта (OF = 0), команда INT type # 3 — за 51 такт. Команда IRET выполняется за 24 такта.

Задача 37. Написать программу умножения 16-разрядных двоичных чисел АХ х DX с вы­ водом на экран дисплея произведения DX:AX в пошаговом режиме. Решение:

s_seg

segment page STACK ; Сегмент стека

 

dw

32 dup (?)

s_seg

ends

; Конец сегмента стека

d_seg

segment

; Сегмент данных

MJDX db

10, ‘ DX = 0000h, AX = 0000/г’, 13, 10

tabl

db

10, ‘ Нажмите любую клавишу’, 10, 13

db

‘0123456789ABCDEF’

; Управляющие ASCII-коды:

;

13d = 0Dh

возврат каретки (сдвиг курсора в левую позицию экрана)

;

10d = h

перевод строки (сдвиг курсора вниз на одну позицию)

;$ — задание конца строки, выводимой на дисплей

d_seg

ends

 

; Конец сегмента данных

cjseg

segment

 

; Сегмент кода

 

assume

CS : c_seg, DS: d_seg, SS: s_seg, ES: d_seg

main

proc

far

; Начало процедуры main

 

push

ds

; Запись в стек начального адреса PSP (Program Segment Prefics)

 

sub

ax, ах

;

и 0000h (для возврата в DOS)

 

push

ax

 

 

 

mov

ax, d_seg

 

 

 

mov

ds, ax

; Инициализация сегментного регистра DS

 

mov

es, ах

; ES = DS

; Получение системного вектора прерывания CSc:IPc для INT 1

 

MOV

АХ, 3501/г

; АН <—35/г — номер функции, AL <— type = 01

 

INT

21 h

; ВХ

М(0000) = IPC, ES <— М(0002) = CSc

 

 

 

; ES:BX = CSc:IPc — адрес подпрограммы INT 1

; INT 21 h, функция DOS 35h — получение вектора прерывания

; Исходное значение указателя стека SP = SP0

 

PUSH

ВХ

; SP <— SP - 2, M(SP0 - 2) <—IPC (сохранение в стеке CSc:IPc)

 

PUSH

ES

; SP <— SP - 2, M(SP0 - 4) CSc