Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
МЕТ_ОРГ_1.doc
Скачиваний:
29
Добавлен:
18.11.2019
Размер:
1.27 Mб
Скачать

Контрольные вопросы

  1. В чем состоит расширение функциональных возможностей МП К1810ВМ86 по сравнению с МП К580ВМ85?

  2. Каково назначение блока преобразования адресов в МП?

  3. Дайте сравнительную характеристику способов адресации?

  4. Чем определяется время формирования исполнительного адреса?

  5. Опишите основной механизм сопряжения по времени работы МП и внешних устройств, имеющих меньшее быстродействие?

  6. Алгоритм формирования физического адреса памяти из логического?

  7. Размер адресного пространства памяти и В/В в системах на базе МП 8086; как адресуются порты В/В?

  8. Составьте последовательность команд, заменяющую команду XLAT?

  9. С помощью каких команд организуется обмен между различными сегментами данных?

  10. Как осуществить вывод содержимого регистра флагов F на ВУ?

  11. В чем состоит различие в использовании флагов CF и OF?

  12. В чем сходство и различие выполнения команд MUL и IMUL, а также DIV и IDIV?

  13. Какие ограничения присущи командам условного перехода?

Теоретическая часть

    1. Способы адресации и оптимизация программ

Команды МП 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. Рассмотрим несколько примеров оптимизации программы по памяти и времени выполнения.

  1. Обнуление регистров

mov

AX, 0

;4 такта, 3 байт

sub

AX, AX

;3 такта, 2 байта

xor

AX, AX

;3 такта,2 байт

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

  1. Загрузка в регистр относительного адреса ячейки памяти

mov

DX, offset mem

;4 такта , 3 байт

1еа

DX, mem

;8 тактов , 4 байт

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

  1. Загрузка в пару регистров полного двухсловного адреса

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) дает существенную экономию и времени, и памяти.

  1. Умножение целого числа на степень двух

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, которое целесообразно заменять сдвигом вправо.