- •По курсу: ”организация эвм и систем”
- •Печатается по решению редакционно-издательского совета
- •Введение
- •1Введение в архитектуру реального режима ibm pc
- •Память и процессор
- •Распределение адресного пространства
- •Система прерываний
- •Система ввода-вывода
- •Архитектурные особенности процессоров ia-32
- •Дополнительные режимы адресации
- •Использование средств 32-разрядных процессоров в программировании
- •2Общие указания по выполнению лабораторных работ
- •Лабораторная работа № 1 Изучение структуры программы и способов адресации мп 8086
- •Домашняя подготовка
- •Лабораторное задание
- •Варианты задания
- •Контрольные вопросы
- •Теоретическая часть
- •Способы адресации и оптимизация программ
- •Строковые команды
- •Сканирование строки.
- •Загрузка регистра из строки.
- •Сегментная структура программ (структура и образ памяти программы .Exe).
- •Двоично-десятичные числа
- •Лабораторная работа № 2. Организация доступа к дискам в режиме ms dos и анализ системных ошибок.
- •Домашняя подготовка
- •Лабораторное задание
- •Варианты заданий
- •Контрольные вопросы
- •Теоретическая часть
- •Лабораторная работа № 3. Организация прерываний и резидентные программы.
- •Домашняя подготовка
- •Лабораторное задание
- •Контрольные вопросы
- •Варианты задания
- •Теоретическая часть (См. Также разделы 1.3 и 2.4)
- •3Организация прерываний и резидентные программы.
- •Резидентные программы
- •Механизм прерываний
- •Структура и образ памяти программы .Сом
- •Примеры резидентных программ
- •Лабораторная работа № 4. Системное время в компьютерах ibm pc
- •Варианты задания
- •Домашняя подготовка
- •Контрольные вопросы
- •Теоретическая часть
- •4 Системное время в компьютерах ibm pc
- •Измерение частоты при помощи rdtsc
- •Назначение каналов таймера в ibm pc
- •Библиографический список
- •Приложение Функции ms dos для выполнения лабораторных работ
- •Установка вектора прерывания
- •Чтение вектора прерывания
- •Завершение программы
- •Создание файла
- •Закрытие файла
- •Чтение из файла
- •Очистка экрана
- •Дополнительные средства ассемблера
Контрольные вопросы
В чем состоит расширение функциональных возможностей МП К1810ВМ86 по сравнению с МП К580ВМ85?
Каково назначение блока преобразования адресов в МП?
Дайте сравнительную характеристику способов адресации?
Чем определяется время формирования исполнительного адреса?
Опишите основной механизм сопряжения по времени работы МП и внешних устройств, имеющих меньшее быстродействие?
Алгоритм формирования физического адреса памяти из логического?
Размер адресного пространства памяти и В/В в системах на базе МП 8086; как адресуются порты В/В?
Составьте последовательность команд, заменяющую команду XLAT?
С помощью каких команд организуется обмен между различными сегментами данных?
Как осуществить вывод содержимого регистра флагов F на ВУ?
В чем состоит различие в использовании флагов CF и OF?
В чем сходство и различие выполнения команд MUL и IMUL, а также DIV и IDIV?
Какие ограничения присущи командам условного перехода?
Теоретическая часть
Способы адресации и оптимизация программ
Команды МП 8086 манипулируют байтами, словами (два байта) строками, двоично-десятичными числами в упакованном и распакованном форматах. Их можно разбить на 6 групп: пересылки, арифметической обработки, логической обработки, обработки строк, передачи управления микропроцессором. Команды занимают в памяти от 1 до 6 байт и имеют форматы 1,2,3,4,5 или 6 байт. Перед командой могут присутствовать байты – префиксы, например, префикс замены сегмента (CS:, DS:, FS:, SS:) или префикс повторения REP.
Обрабатываемые в программе данные можно помещать в регистры МП (регистровый способ адреса), записывать в качестве одного из операндов прямо в команде (непосредственная адресация), либо тем или иным способом указывать место в памяти, где эти данные расположены. Способ доступа к данным кодируется в команде формой записи адресного выражения. Основу любых адресных выражений образуют такие простейшие элементы, как константы, переменные и метки.
Каждое адресное выражение проверяется Ассемблером на допустимость его применения в конкретной операции и затем генерируется соответствующая машинная команда. Так, если метки образуют основу операндов в командах передачи управления, то переменные – основу адресных выражений во всех других командах. Например, по команде MOV AX, NAME будет сформирована машинная команда с непосредственным операндом, если NAME – поименованная константа, или машинная команда с прямой адресацией, если NAME – переменная типа WORD. В остальных случаях будет выдано сообщение об ошибке.
Способы адресации и оптимизация программ рассмотрим на конкретных примерах.
Пример 1. Поиск максимального значения:
; Сегмент данных |
|
||
mas |
db |
1,2,5,3,7,9,8,3,4 |
; Исходные данные |
num= |
$-mas |
|
; число байт (элементов) в массиве |
; Сегмент команд |
|
||
|
mov |
DL, mas |
; (1) DL=первый элемент массива |
|
mov |
CX, num-1 |
; (2) СХ=число сравниваемых элементов минус один (первый). |
|
mov |
BX, 1 |
; (3) ВХ=индекс второго элемента |
Cont: |
cmp |
DL, mas[BX] |
; (4) DL> следующего элемента |
|
jg |
Next |
; (5) Если да, то на анализ следующего элемента |
|
mov |
DL, mas[BX] |
; (6) Если нет, то в DL заносим следующий элемент |
Next: |
Inc |
BX |
; (7) И на анализ следующего элемента |
|
loop |
Cont |
; (8) Цикл СХ раз |
В предложении 1 в регистр DL заносится содержимое первого байта последовательности данных, которая в этой программе обозначена как mas. Здесь мы сразу же встречаемся с двумя способами адресации данных - регистровым и прямым (прямая адресация к памяти). При использовании регистровой адресации данные записываются в регистр – однобайтовый или двухбайтовый. Прямой способ адресации является представителем группы способов обращения к данным, которые хранятся не в регистрах, а в ячейках памяти. В рассматриваемом случае при прямой адресации имя mas фактически является адресом памяти, то есть смещением в сегменте данных, начиная с которого хранятся данные. При этом в качестве сегментного регистра по умолчанию используется регистр DS. Содержимое указанной ячейки памяти переносится (в данном случае) в регистр DL. Если рассматриваемая ячейка памяти располагается в сегменте, базовый адрес которого находится в другом сегментном регистре (ES, CS или SS), то обязательно указание этого регистра: mov DL, ES:mas.
Еще один способ адресации представлен в предложении 3, где в качестве одного из операндов указано число (конкретно 1). Такой операнд входит непосредственно в состав команды процессора. Этот способ адресации так и называется - непосредственный. В предложениях 4 и 5 применена разновидность прямой адресации к памяти, в которой указывается не только обозначение ячейки памяти (mas), но и величина сдвига относительно этой ячейки (в данном случае в регистре ВХ). Очевидно, что такой способ адресации удобен при работе с массивами.
Все имеющиеся способы адресации можно условно разделить на три группы:
непосредственный;
регистровый;
с указанием адреса памяти, при этом адрес памяти можно задавать по-разному: прямым указанием символического обозначения ячейки памяти, указанием регистра, в котором хранится требуемый адрес, или и того, и другого.
Таким образом, третья группа включает, в сущности, целый ряд способов адресации. К ним относятся: прямая, базовая, индексная, базово - индексная, а также базовая, индексная или базово - индексная со смещением.
Приведем краткий обзор способов адресации.
Регистровая адресация: операнд (байт или слово) находится в регистре. Способ применим ко всем программно - адресуемым регистрам процессора.
Пример 2:
Push |
DS |
; Сохранение DS в стеке |
Mov |
BP, SP |
; Пересылка содержимого SP в BP |
Непосредственная адресация: операнд (байт или слово) может быть представлен в виде числа, адреса, кода ASCII, а так же иметь символьное обозначение.
Пример 3:
Mov |
AX, 4C00h |
; Операнд – число в 16-ричной СС |
||
Mov |
DX, offset mas |
; Адрес (смещение) массива mas заносим в регистр DX |
||
Mov |
DL, ′!′ |
; операнд – код ASCII символа “!” |
||
|
Num =9 |
;Число 9 получает обозначение num |
||
Mov |
CX, num |
;Число, обозначенное num, загружается в регистр СХ |
Прямая адресация к памяти: в команде указывается символическое обозначение ячейки памяти, над содержимым которой требуется выполнить операцию.
Пример 4:
Mov |
DL, mem1 |
; Содержимое байта памяти с символическим именем mem1 пересылается в DL |
Если нужно обратиться к ячейке памяти с известным абсолютным адресом, то этот адрес можно непосредственно указать в качестве операнда. Предварительно необходимо настроить какой-либо сегментный регистр на начало того участка памяти, в котором находится искомая ячейка.
Пример 5 :
Mov |
АХ, 0 |
;Настроим сегментный регистр на |
Mov |
ES, AX |
; самое начало памяти (адрес 0) |
Mov |
AX,ES:[0] |
;Заберем в АХ содержимое слова памяти по адресу 0000:0000 |
Заметим, что в этом случае сегментный регистр указывать обязательно.
Косвенные способы адресации к памяти. Базовая или индексная адресация: относительный адрес ячейки памяти находится в регистре, обозначение которого заключается в квадратные скобки. При использовании регистров ВХ или ВР адресацию называют базовой, при использовании регистров SI или DI - индексной. При адресации через регистры ВХ, SI или DI в качестве сегментного регистра подразумевается DS; при адресации через ВР - SS. Таким образом, косвенная адресация через регистр ВР предназначена для работы со стеком. Однако при необходимости можно явно указать требуемый сегментный регистр.
Пример 6:
Mov |
AL,[BX] |
;Сегментный адрес предполагается в DS, смещение в ВХ |
Mov |
DL,ES:[BX] |
;Сегментный адрес находится в ES, смещение в ВХ |
Mov |
DХ,[ВР] |
;Сегментный адрес предполагается в SS, смещение в ВР |
Mov |
AL,[DI] |
;Сегментный адрес предполагается в DS, смещение в DI |
Базовая или индексная адресация со смещением: относительный адрес операнда определяется суммой содержимого регистра (ВХ, ВР, SI или DI) и указанного в команде числа, которое довольно неудачно называют смещением.
Пример 7:
mas db |
1, 2, 5, 3, 7, 9, 8, 3, 4 |
;Массив символов |
Mov |
ВХ, 2 |
;ВХ= индекс элемента в массиве |
Mov |
DL, mas[BX] |
;В DL заносится третий элемент массива |
В этом примере относительный адрес адресуемого элемента массива mas вычисляется как сумма содержимого регистра ВХ (2) и значения символического обозначения mas, которое совпадает с относительным адресом начала массива mas. В результате в регистр DL будет загружен элемент массива mas с индексом 2, то есть число 5. Предполагается, что базовый адрес сегмента, в который входит массив mas, загружен в сегментный регистр DS. Такой же результат можно получить при выполнении следующей последовательности команд:
mov |
ВХ, offset mas |
;ВХ=относительный адрес ячейки mas |
mov |
DL, 2[BX] |
|
Здесь относительный адрес адресуемого элемента массива mas вычисляется как сумма содержимого регистра ВХ и дополнительного смещения, задаваемого константой 2. Последняя команда может быть записана в следующем виде:
mov |
DL,[BX+2] |
mov |
DL,[BX]+2 |
Адресация с помощью регистров SI и DI осуществляется аналогично. При использовании регистра ВР следует помнить, что в качестве сегментного регистра по умолчанию подразумевается регистр SS.
Базово-индексная адресация. Относительный адрес операнда определяется суммой содержимого базового и индексного регистров. Допускается использование следующих пар:
[BX] [SI]; [BP] [SI];
[BX] [DI]; [BP] [DI];
Если в качестве вазового регистра выступает BX, то в качестве сегментного подразумевается DS (первые две команды), при использовании в качестве базового регистра ВР сегментным регистром по умолчанию назначается SS (вторые две команды). При необходимости можно явно указать требуемый сегментный регистр.
Пример 8:
mov |
BX,[BP][SI] |
;В ВХ засылается слово из стека (сегментный адрес находится в SS), а смещение вычисляется как сумма содержимого ВР и SI |
Mov |
ES:[BX+DI],AX |
;В ячейку памяти, сегментный адрес которой хранится в ES, а смещение вычисляется как сумма содержимого ВХ и DI, пересылается содержимое АХ |
Базово-индексная адресация со смещением: относительный адрес операнда определяется суммой трех величин: содержимого базового и индексного регистров, а также дополнительного смещения. Допускается использование тех же пар регистров, что и в базово-индексном способе; так же действуют и правила определения сегментных регистров.
Пример 9 :
mov |
mas[BX][SI],10 |
;Символ с кодом 10 - "возврат каретки" - пересылается в ячейку памяти, сегментный адрес которой хранится в DS, а смещение равно сумме содержимого ВХ, SI и относительного адреса ячейки mas |
Mov |
AX,[BP+2+ DI] |
;В АХ пересылается из стека слово, смещение которого равно сумме ВР, DI и добавки, равной двум |
Значительная часть рассмотренных выше способов адресации служит для обращения к ячейкам памяти. Таким образом, один и тот же конечный результат можно получить с помощью различных способов адресации. Например, все три приведенные ниже команды:
mov |
DL,mas+3 |
|
mov |
DL,mas[BX] |
; В ВХ заранее занесено число 3 |
mov |
DL,[SI][BX] |
; В ВХ заранее занесено число 3, а в SI - смещение mas |
приведут к загрузке в регистр DL четвертого элемента массива mas (если выполняются описанные в комментариях условия). Однако команды с использованием различных способов адресации занимают различный объем памяти и выполняются за разное время. Так, первая из приведенных выше команд потребует для выполнения 15 машинных тактов, вторая - 18, а третья - 16. Разница невелика, однако при многократном выполнении команд в циклах суммарный эффект может быть значителен. С другой стороны, первые две команды занимают в памяти по 4 байта, а третья только 2. Таким образом, тщательный выбор способов адресации позволяет в какой-то степени оптимизировать программы по времени выполнения или требуемой памяти, а иногда и по тому, и по другому.
Время выполнения команды можно определить, разделив требуемое для ее выполнения число машинных тактов на частоту работы конкретного процессора. Последняя величина колеблется для используемых в настоящее время персональных компьютеров в очень широких пределах - от сотен МГц до единиц ГГц и более. Поэтому время выполнения команд и всей программы в целом оценивают обычно не в абсолютных величинах, а именно в числе машинных тактов.
Полное время выполнения команды можно выразить в виде суммы двух составляющих: базового времени выполнения команды, которое зависит от вида команды и способа адресации, и времени вычисления исполнительного адреса, если операнд находится в памяти. Вторая оставляющая тоже зависит от способа адресации. Разброс времен выполнения для разных команд может быть весьма значителен. Так, команда сложения содержимого двух регистров требует 3 тактов, прямого внутрисегментного перехода - 15 тактов, а команда деления - около 100 тактов. То же, хотя и в меньшей степени, относится к времени вычисления исполнительного адреса. Если смещение ячейки памяти указывается в регистре (базовом или индексном), то к базовому времени выполнения команды следует прибавить 5 тактов, при базово-индексной адресации - 8, а в случае базово-индексной адресации со смещением - 12. Рассмотрим несколько примеров оптимизации программы по памяти и времени выполнения.
Обнуление регистров
mov |
AX, 0 |
;4 такта, 3 байт |
sub |
AX, AX |
;3 такта, 2 байта |
xor |
AX, AX |
;3 такта,2 байт |
Видно, что первая команда, будучи наиболее наглядной, в то же время уступает двум другим по своим оптимизационным характеристикам.
Загрузка в регистр относительного адреса ячейки памяти
mov |
DX, offset mem |
;4 такта , 3 байт |
1еа |
DX, mem |
;8 тактов , 4 байт |
Первый способ загрузки в регистр смещения ячейки оказывается лучше во всех отношениях. С другой стороны, команда lеа имеет больше возможностей, поскольку в ней можно использовать любые способы адресации.
Загрузка в пару регистров полного двухсловного адреса
addr |
dd array_l |
;Полный адрес массива array_l в двухсловной ячейке addr |
mov |
BX, word ptr addr |
;Получение смещения, 14 тактов, 4 байт |
mov |
ES, word ptr addr+2 |
;Сегмент, 14 тактов, 4 байт |
les |
BX, addr |
;Получение сегмента и смещения, 16 тактов, 4 байт |
Результат выполнения двух первых команд такой же, как и одной третьей. Однако использование команды les (или lds для загрузки сегментного регистра DS) дает существенную экономию и времени, и памяти.
Умножение целого числа на степень двух
mov |
BX, 32 |
;Сомножитель в ВХ, 4 такта, 3 байт |
mu1 |
BX |
;Умножение, до 133 тактов, 2 байта |
mov |
CL, 5 |
;Величина сдвига, 4 такта, 3 байт |
sal |
AX, CL |
;Сдвиг, 28 тактов, 2 байт |
Последний пример несколько специфичен. Если вам необходимо умножить на степень числа 2 (2,4,8,16,...), выполнение этой операции можно существенно ускорить, заменив умножение сдвигом влево на число позиций, равное показателю степени. Каждый сдвиг влево на одну позицию приводит к умножению на два. Таким образом, первая и вторая пары команд в вышеприведенном примере эквивалентны по результату, но замена умножения сдвигом позволяет ускорить операцию в несколько раз. Те же рассуждения применимы к делению на степень числа 2, которое целесообразно заменять сдвигом вправо.