Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
мк экз.docx
Скачиваний:
22
Добавлен:
01.04.2022
Размер:
2.93 Mб
Скачать

Способы адресации

Косвенная адресация

Косвенную адресацию можно выполнить с помощью загрузки косвенных адресов в регистры Н и L, используя команду LHLD.

Таким образом, этот процесс всегда включает два шага. Кроме того, можно использовать также пары регистров В и D в командах LDAX и STAX.

Индексная адресация

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

Предувеличение

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

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

Послеувеличение

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

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

Предуменьшение

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

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

Послеуменьшение

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

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

Косвенная адресация с предварительным индексированием (предындексирование)

При предындексировании процессор должен сначала вычислить индексный адрес, а затем использовать этот адрес косвенно.

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

Косвенная адресация с последующим индексированием (послеиндексирование)

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

4

Директивы

Директивы являются указаниями Ассемблеру о том, как проводить ассемблирование.

Директив может быть великое множество. В 1-м приближении мы рассмотрим лишь несколько практически обязательных директивы (мнемоники директив везде — условные, в конкретных Ассемблерах те же по смыслу директивы могут иметь другие мнемоники).

EQU

Определение имени

Перед этой директивой обязательно стоит имя. Операнд этой директивы определяет значение имени.

Операндом может быть и выражение, вычисляемое при ассемблировании. Имя может определяться и через другое имя, определенное выше. Как правило, не допускается определение имени со ссылкой вперед.

DD

Определение данных

Выделяются ячейки памяти и в них записываются значения, определяемые операндом директивы.

Перед директивой может стоять метка/имя. Как правило, одной директивой могут определяться несколько объектов данных.

В конкретных Ассемблерах может существовать либо одна общая директива DD, тогда тип данных, размещаемых в памяти определяется формой записи операндов, либо несколько подобных директив — для разных типов данных.

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

BSS

Резервирование памяти

Выделяются ячейки памяти, но значения в них не записываются. Объем выделяемой памяти определяется операндом директивы.

Перед директивой может стоять метка/имя.

END

Конец программного модуля

Указание Ассемблеру на прекращение трансляции. Обычно в модуле, являющемся главным (main) операндом этой директивы является имя точки, на которую передается управление при начале выполнения программы. Во всех других модулях эта директива употребляется без операндов.

4

Директивы определения данных

Сегмент данных предназначен для определения констант, рабочих полей и областей для ввода-вывода. В соответствии с имеющимися директивами в Ассемблере разрешено определение данных различной длины: например, директива DB определяет байт, а директива DW oпределяет слово. Элемент данных может содержать непосредственное значение или константу, определенную как символьная строка или как числовое значение.

Другим способом определения константы является непосредственное значение, то есть, указанное прямо в ассемблерной команде, например:

MOV AL,20H

В этом случае шестнадцатеричное число 20 становится частью машинного объектного кода. Непосредственное значение ограничено oдним байтом или одним словом, но там, где оно может быть применено, оно является более эффективным, чем использование конcтанты.

Ассемблер обеспечивает два способа определения данных: во-первых, через указание длины данных и, во-вторых, по их cодержимому. Рассмотрим основной формат определения данных:

[имя] Dn выражение

Имя элемента данных не обязательно (это указывается квадратными скобками), но если в программе имеются ссылки на некоторый элемент, то это делается посредством имени.

Для определения элементов данных имеются следующие директивы: DB (байт), DW (слово), DD (двойное слово), DQ (учетверенное слово) и DT (десять байт).

Выражение может содержать константу, например:

FLD1 DB 25

или знак вопроса для неопределенного значения, например

FLDB DB ?

Выражение может содержать несколько констант, разделенных запятыми и ограниченными только длиной строки:

FLD3 DB 11, 12, 13, 14, 15, 16, ...

Ассемблер определяет эти константы в виде последовательности cмежных байт.

Ссылка по имени FLD3 указывает на первую константу, 11, по FLD3+1 — на вторую, 12. (FLD3 можно представить как FLD3+0). Например команда

MOV AL,FLD3+3

загружает в регистр AL значение 14 (шест. 0E). Выражение допускает также повторение константы в следующем формате:

[имя] Dn число-повторений DUP (выражение) ...

Следующие три примера иллюстрируют повторение:

DW 10 DUP(?) ;Десять неопределенных слов

DB 5 DUP(14) ;Пять байт, содержащих шест.14

DB 3 DUP(4 DUP(8));Двенадцать восьмерок

В третьем примере сначала генерируется четыре копии десятичной 8 (8888), и затем это значение повторяется три раза, давая в pезультате двенадцать восьмерок.

Выражение может содержать символьную строку или числовую константу.

Символьные строки

Символьная строка используются для описания данных, таких как, например, имена людей или заголовки страниц. Содержимое строки oтмечается одиночными кавычками, например, 'PC' или двойными кавычками — "PC".

Ассемблер переводит символьные строки в объектный код в обычном формате ASCII.

Символьная строка определяется только директивой DB, в котоpой указывается более двух символов в нормальной последовательности слева направо. Следовательно, директива DB представляет единственно возможный формат для определения символьных данных.

Числовые константы

Числовые константы используются для арифметических величин и для aдресов памяти. Для описания константы кавычки не ставятся. Ассемблер преобразует все числовые константы в шестнадцатеричные и записывает байты в объектном коде в обратной последовательности — справа налево. Ниже показаны различные числовые форматы.

Десятичный формат

Десятичный формат допускает десятичные цифры от 0 до 9 и обозначается последней буквой D, которую можно не указывать, например, 125 или 125D. Несмотря на то, что Ассемблер позволяет кодирование в десятичном формате, он преобразует эти значения в шест. объектный код. Например, десятичное число 125 преобразуется в шест.7D.

Шестнадцатеричный формат

Шестнадцатеричный формат допускает шест. цифры от 0 до F и обозначается последней буквой H.

Так как Ассемблер полагает, что с буквы начинаются идентификаторы, то первой цифрой шест. константы должна быть цифра от 0 до 9. Например, 2EH или 0FFFH, которые Ассемблер преобразует соответственно в 2E и FF0F (байты во втором примере записываются в объектный код в обратной последовательности).

Двоичный формат

Двоичный формат допускает двоичные цифры 0 и 1 и обозначается последней буквой B. Двоичный формат обычно используется для более четкого представления битовых значений в логических командах AND, OR, XOR и TEST. Десятичное 12, шест. C и двоичное 1100B все генерируют один и тот же код: шест. 0C или двоичное 0000 1100 в зависимости от того, как вы рассматриваете содержимое байта.

Восьмеричный формат

Восьмеричный формат допускает восьмеричные цифры от 0 до 7 и обозначается последней буквой Q или O, например, 253Q. На сегодня восьмеричный формат используется весьма редко.

Десятичный формат с плавающей точкой

Этот формат поддерживается только Ассемблером МASM. При записи символьных и числовых констант следует помнить, что, например, символьная константа, определенная как DB '12', представляет символы ASCII и генерирует шест.3132, а числовая константа, oпределенная как DB 12, представляет двоичное число и генерирует шест.0C.

4

Директива определения байта (DB)

Из различных директив, определяющих элементы данных, наиболее полезной является DB (определить байт). Символьное выражение в диpективе DB может содержать строку символов любой длины, вплоть до конца строки. Объектный код показывает символы кода ASCII для каждого байта. Шест.20 представляет символ пробела.

Числовое выражение в директиве DB может содержать одну или более однобайтовых констант. Один байт выражается двумя шест. цифpами.

Наибольшее положительное шест. число в одном байте это 7F, все «большие» числа от 80 до FF представляют отрицательные значения. В десятичном исчислении эти пределы выражаются числами +127 и -128.

4

Директива определения слова (DW)

Директива DW определяет элементы, которые имеют длину в одно слово (два байта). Символьное выражение в DW ограничено двумя символами, которые Ассемблер представляет в объектном коде так, что, например, 'PC' становится 'CP'. Для определения символьных строк директива DW имеет ограниченное применение.

Числовое выражение в DW может содержать одно или более двухбайтовых констант. Два байта представляются четырьмя шест. цифрами. Наибольшее положительное шест. число в двух байтах это 7FFF; все «большие» числа от 8000 до FFFF представляют отрицательные значения. В десятичном исчислении эти пределы выражаются числами +32767 и -32768. Для форматов директив DW, DD и DQ Ассемблер преобразует константы в шест. объектный код, но записывает его в обратной последовательности. Таким образом десятичное значение 12345 преобразуется в шест.3039, но записывается в объектном коде как 3930.

4

Директива определения двойного слова (DD)

Директива DD определяет элементы, которые имеют длину в два cлова (четыре байта). Числовое выражение может содержать одну или более констант, каждая из которых имеет максимум четыре байта (восемь шест. цифр).

Наибольшее положительное шест. число в четырех байтах это 7FFFFFFF; все «большие» числа от 80000000 до FFFFFFFF представляют отрицательные значения.

В десятичном исчислении эти пределы выражаются числами +2147483647 и -2147483648.

Ассемблер преобразует все числовые константы в директиве DD в шест. представление, но записывает объектный код в обратной последовательности.

Таким образом десятичное значение 12345 преобразуется в шест.00003039, но записывается в oбъектном коде как 39300000.

Символьное выражение директивы DD ограничено двумя символами. Ассемблер преобразует символы и выравнивает их слева в четырехбайтовом двойном слове, как показано в поле FLD2DD в объектном коде.

4

Директива определения учетверенного слова (DQ)

Директива DQ определяет элементы, имеющие длину четыре слова (восемь байт). Числовое выражение может содержать одну или более констант, каждая из которых имеет максимум восемь байт или 16 шест. цифр. Наибольшее положительное шест. число — это семерка и 15 цифр F. Для получения представления о величине этого числа, покажем, что шест. 1 и 15 нулей эквивалентен следующему десятичному числу:

1152921504606846976

Ассемблер преобразует все числовые константы в директиве DQ в шест. представление, но записывает объектный код в обратной последовательности, как и в директивах DD и DW.

Обработка Ассемблером символьных строк в директиве DQ aналогична директивам DD и DW.

4

Директива определения десяти байт (DT)

Директива DT определяет элементы данных, имеющие длину в десять байт.

Назначение этой директивы связано с «упакованными десятичными» числовыми величинами.

По директиве DT генерируются различные константы, в зависимости от версии Ассемблера.

4

Непосредственные операнды

Ранее было показано использование непосредственных операндов. Команда:

MOV AX,0123H

пересылает непосредственную шест. константу 0123 в регистр AX.

Трехбайтный объектный код для этой команды есть B82301, где B8 обозначает «переслать непосредственное значение в регистр AX», a следующие два байта содержат само значение.

Многие команды имеют два операнда: первый может быть регистр или адрес памяти, а второй — непосредственная константа.

Использование непосредственного операнда более эффективно, чем oпределение числовой константы в сегменте данных и организация cсылки на нее в операнде команды MOV, например,

Сегмент данных: AMT1 DW 0123H

Сегмент кодов: MOV AX,AMT1

Длина непосредственных операндов

Длина непосредственной константы зависит от длины первого операнда. Например, следующий непосредственный операнд является двухбайтовым, но регистр AL имеет только один байт:

MOV AL,0123H (ошибка)

Однако, если непосредственный операнд короче, чем получающий операнд, как в следующем примере

ADD AX,25H (нет ошибки)

то Ассемблер расширяет непосредственный операнд до двух байт, 0025 и записывает объектный код в виде 2500.

Непосредственные форматы

Непосредственная константа может быть шестнадцатеричной, например, 0123H; десятичной, например, 291 (которую Ассемблер конвертирует в шест.0123); или двоичной, например, 100100011В (которая преобразуется в шест. 0123). Ниже приведен список команд, которые допускают непосредственные операнды:

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

MOV, CMP.

Арифметические команды

ADC, ADD, SBB, SUB.

Команды сдвига

RCL, RCR, ROL, ROR, SHL, SAR, SHR.

Логические команды

AND, OR, TEST, XOR.

Для создания элементов, длиннее чем два байта, можно использовать цикл или строковые команды.

4

Директива EQU

Директива EQU не определяет элемент данных, но определяет значение, которое может быть использовано для постановки в других командах. Предположим, что в сегменте данных закодирована следующая директива EQU:

TIMES EQU 10

Имя, в данном случае TIMES, может быть представлено любым допустимым в Ассемблере именем. Теперь, в какой бы команде или директиве не использовалось слово TIMES Ассемблер подставит значение 10. Например, Ассемблер преобразует директиву

FIELDA DB TIMES DUP (?) в FIELDA DB 10 DUP (?)

Имя, связанное с некоторым значением с помощью директивы EQU, может использоваться в командах, например:

COUNTR EQU 05 ...

MOV CX,COUNTR

Ассемблер заменяет имя COUNTR в команде MOV на значение 05, cоздавая операнд с непосредственным значением, как если бы было закодировано:

MOV CX,05 ;Ассемблер подставляет 05

Здесь преимущество директивы EQU заключается в том, что многие команды могут использовать значение, определенное по имени COUNTR. В случае, если это значение должно быть изменено, то изменению подлежит лишь одна директива EQU. Естественно, что использование директивы EQU разумно лишь там, где подстановка имеет смысл для Ассемблера. В директиве EQU можно использовать символические имена:

1. TP EQU TOTALPAY

2. MPY EQU MUL

Первый пример предполагает, что в сегменте данных программы опpеделено имя TOTALPAY. Для любой команды, содержащей операнд TP, Ассемблер заменит его на адрес TOTALPAY. Второй пример показывает возможность использования в программе слова MPY вместо обычного мнемокода MUL.

Лекция 3.

Регистры

4

Сегментные регистры: CS, DS, SS и ES

Каждый сегментный регистр обеспечивает адресацию 64 К памяти, которая называется текущим сегментом. Как показано ранее, cегмент выравнен на границу параграфа и его адрес в сегментном pегистре предполагает наличие справа четырех нулевых битов.

Регистр CS

Регистр сегмента кода содержит начальный адрес сегмента кода. Этот адрес плюс величина смещения в командном указателе (IP) определяет адрес команды, которая должна быть выбрана для выполнения. Для обычных программ нет необходимости делать ссылки на регистр CS.

Регистр DS

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

Регистр SS

Регистр сегмента стека содержит начальный адрес в сегменте стека.

Регистр ES

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

4

Регистры общего назначения: AX, BX, CX и DX

При программировании на Ассемблере регистры общего назначения являются «рабочими лошадками». Особенность этих регистров состоит в том, что возможна адресация их как одного целого слова или как oднобайтовой части. Левый байт является старшей частью (high), a правый — младшей частью (low). Например, двухбайтовый регистр CX состоит из двух однобайтовых: CH и CL, и ссылки на регистр возможны по любому из этих трех имен. Следующие три ассемблерные команды засылают нули в регистры CX, CH и CL, соответственно:

MOV CX,00

MOV CH,00

MOV CL,00

Регистр AX

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

Некоторые команды генерируют более эффективный код, если они имеют ссылки на регистр AX.

AX: | AH | AL |

Регистр BX

Регистр BX является базовым регистром. Это единственный регистр общего назначения, который может использоваться в качестве «индекса» для расширенной адресации. Другое общее применение его — вычисления.

BX: | BH | BL |

Регистр CX

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

CX: | CH | CL |

Регистр DX

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

DX: | DH | DL |

Любые регистры общего назначения могут использоваться для cложения и вычитания как 8-ми, так и 16-ти битовых значений.

4

Регистровые указатели: SP и BP

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

Регистр SP

Указатель стека обеспечивает использование стека в памяти, позволяет временно хранить адреса и иногда данные.

Этот регистр связан с регистром SS для адресации стека.

Регистр BP

Указатель базы облегчает доступ к параметрам: данным и адресам переданным через стек.

4

Индексные регистры: SI и DI

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

Регистр SI

Этот регистр является индексом источника и применяется для некоторых операций над строками. В данном контексте регистр SI связан с регистром DS.

Регистр DI

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

4

Регистр командного указателя: IP

Регистр IP содержит смещение на команду, которая должна быть выполнена. Обычно этот регистр в программе не используется, но он может изменять свое значение при использовании отладчика DOS DEBUG для тестирования программы.

4

Флаговый регистр

Девять из 16 битов флагового регистра являются активными и определяют текущее состояние машины и результатов выполнения. Многие арифметические команды и команды сравнения изменяют состояние флагов.

Назначение флаговых битов

O (Переполнение)

Указывает на переполнение старшего бита при арифметических командах.

D (Направление)

Обозначает левое или правое направление пересылки или сравнения строковых данных (данных в памяти превышающих длину одного слова).