div.main {margin-left: 20pt; margin-right: 20pt}
ЯЗЫК АССЕМБЛЕРА МИКРОПРОЦЕССОРА 8086
Язык
ассемблера представляет собой машинный язык в символической форме, которая
более понятна и удобна человеку.
Язык
ассемблера микропроцессора Intel 8086 является довольно сложным, что в первую
очередь объясняется сегментной организацией памяти и одновременной адресацией
четырех сегментов. В языке имеется более 100 базовых символических команд, в
соответствии с которыми ассемблер генерирует более 3800 машинных команд. Кроме
того, в распоряжении программиста имеется более 20 директив, предназначенных для
распределения памяти, инициализации переменных, условного ассемблирования и
т.д.
Исходная программа на языке ассемблера представляет собой последовательность
операторов. Операторы обычно занимают одну строку. Ассемблер воспринимает
операторы в свободном формате, т.е. элементам операторов не назначены
фиксированные столбцы и между ними может быть любое число пробелов там, где это
необходимо.
Операторы
в исходной программе классифицируются как командные операторы, операторы
распределения данных и директивы ассемблера.
Командные
операторы определяют генерируемые ассемблером машинные команды; они
содержат мнемонику и, при необходимости, один или два операнда. Каждый командный
оператор порождает одну машинную команду, формат которой зависит от способа
задания операндов.
Операторы
распределения данных резервируют ячейки памяти для данных программы.
Директивы
ассемблера содержат специальные указания для ассемблирующей программы и сами по
себе не порождают никаких машинных кодов.
Формат командных операторов
Командные
операторы записываются в следующем формате:
Метка:
Префикс Мнемоника Операнд1,Операнд2 ;Комментарий
где
фигурные скобки обозначают необязательные поля.
Рассмотрим
назначение отдельных полей данного формата:
1)
Метка представляет собой определяемое пользователем имя, заканчивающееся
двоеточием. Значением метки является текущее значение счетчика ячеек (адресов) в
текущем сегменте кода, т.е. адрес отмеченной команды. Метки как операнды
используются только в командах передачи управления, и при этом двоеточие в конце
ссылки на метку не ставится.
2)
Префикс заставляет ассемблер сформировать один из префиксных байт - блокировки
LOCK или повторения REP, который непосредственно предшествует команде.
3)
Мнемоника кода операции представляет собой заранее определенное и
неизменяемое имя, которое идентифицирует тип генерируемой машинной
команды.
4)
Операнды задают адреса данных или сами данные, необходимые в данной
команде.
5)
Комментарий предназначен только для документирования программы. Он всегда
начинается с точки с запятой.
Формат директив ассемблера
и
операторов распределения данных
Директивы
ассемблера и операторы распределения данных имеют несколько иной формат:
Имя
Директива Операнды ;Комментарий
Рассмотрим
назначение отдельных полей данного формата:
1)
Имя директивы, в отличие от метки, никогда не заканчивается двоеточием.
Некоторые директивы требуют обязательного наличия метки.
2)
Директива является одним из ключевых неизменяемых слов ассемблера и определяет
его действия в процессе ассемблирования. Директивы используются программистом
для распределения памяти, обеспечения связи между программными модулями и работы
с символическими именами.
3)
Операнды конкретизируют действия, выполняемые по данной директиве.
4)
Поле комментария аналогично такому же полю в командных операторах.
ЭЛЕМЕНТЫ ОПЕРАТОРОВ
Дадим
определения основных терминов, которые будут использованы в
дальнейшем.
Ключевые
(зарезервированные) слова представляют собой имена, имеющие для ассемблера
строго определенный смысл. Их нельзя использовать в качестве
идентификаторов.
Идентификатор
как общий термин для меток и имен переменных - это определяемая программистом
последовательность символов. Первым символом в последовательности должна
быть буква или один из символов @, подчеркивание или знак вопроса. В качестве
последующих символов можно также использовать цифры. Максимальная длина
идентификатора 31 символ.
Ассемблер
процессора 8086 является жестко типизированным языком. Это означает, что
операнды команд (регистры, переменные,
метки,
константы) имеют связанный с ними
атрибут типа, который
сообщает
ассемблеру некоторую
информацию об операнде. Атрибут
типа
обычно подразумевается по умолчанию,
но при необходимости
может
быть задан явно.
Регистры
8-разрядным
регистрам AL, AH, BL, BH, CL, CH, DL, DH приписан тип BYTE, а 16-разрядным
регистрам AX, BX, CX, DX, BP, SP, SI, DI и сегментным регистрам CS, DS, SS, ES
приписан тип WORD.
Разряды
регистра флажков представляют собой однобитные регисты, для установки и
сброса каждого из которых используются отдельные машинные команды.
Переменные
При
программировании может возникнуть необходимость многократного обращения к
данным. Вместо того, чтобы оперировать громоздкими численными значениями
адресов, удобно определять и применять символические имена, соответствующие
адресам указанных элементов.
Переменная
- это единица программных данных, имеющая символическое имя.
Большинство
ассемблерных программ начинается с определения данных, которыми они будут
оперировать. Распределение ячеек памяти и присвоение им идентификаторов
осуществляется с помощью директив DB (Define Byte - определить байт), DW (Define
Word - определить слово), DD (Define Doubleword - определить двойное слово), DQ
(Define Quadword - определить 4 слова) или DT (Define Tenbyte - определить 10
байтов).
Операторы
распределения данных имеют следующий формат:
Имя
DB нач.значение, нач.значение, ...
Имя
DW нач.значение, нач.значение, ...
Имя
DD нач.значение, нач.значение, ...
Имя
DQ нач.значение, нач.значение, ...
Имя
DT нач.значение, нач.значение, ...
Таким
образом, каждая директива может инициировать одну или несколько переменных
соответствующего типа.
Для
задания начальных значений могут использоваться числовые константы и символьные
цепочки. Если не нужно задавать начальное значение переменной, то вместо
константы ставится вопросительный знак.
Например,
оператор alpha DW 0Ah
резервирует слово
памяти, присваивает ему
идентификатор alpha и
заносит в него код
000A;
string DB 'Привет'
резервирует
6 байт памяти и
заносит в них строку символов и
присваивает этой
строке идентификатор string.
Чтобы
точно определить тип переменной, на которую производится ссылка, ассемблер
использует операторы BYTE PTR, WORD PTR и DWORD PTR (указатель на байт, слово и
двойное слово соответственно).
Для
инициализации массивов применяется конструкция DUP, которая в общем случае имеет
вид:
n DUP (нач. значение, нач. значение,
...)
где
параметр n задает число повторений элементов,
находящихся в
круглых
скобках.
Например,
оператор Addr DD 20 DUP (?)
резервирует место
для 20 полных адресов и
присваивает этому
массиву
идентификатор Addr.
Метки
Метка
представляет собой символическое имя для адреса ячейки памяти и предназначена
для использования в качестве операнда в командах управления.
Числовые
константы
Константа
- это численное значение, вычисляемое во время ассемблирования по заданному
выражению.
Численные
константы допускается представлять в системах счисления с основаниями 2, 8, 10 и
16. За младшей цифрой должен находиться однобуквенный дескриптор системы
счисления: B - двоичная, O или Q - восьмеричная, D (необязательно) -
десятичная, H-шестнадцатиричная. Шестнадцатиричная константа должна быть
дополнена слева незначащим нулем.
Символьные константы
Символьная
константа - это любой символ в коде ASCII. Символьная строка может содержать до
255 символов и должна быть заключена в одиночные кавычки.
СЕГМЕНТЫ И ПРОЦЕДУРЫ
Программы,
написанные на языке ассемблера процессора 8086, могут быть разделены на один или
несколько сегментов. Каждый логический сегмент имеет уникальное имя и однозначно
отображается в сегментах памяти при загрузке программы для ее выполнения. Для
определения начальной и конечной ячеек логического сегмента в макроассемблере
предусмотрены директивы SEGMENT (начало сегмента) и ENDS (конец сегмента).
Обычно
часть программы, содержащая коды машинных команд,
объединяется
в кодовый сегмент. Переменные,
константы, таблицы и
другие
данные объединяются в сегмент данных. Для хранения промежуточных данных и
при вызове подпрограмм используется сегмент стека. Иногда для хранения данных
может использоваться четвертый, дополнительный сегмент.
Директива
ASSUME указывает ассемблеру, к какому сегментному регистру относится тот или
иной логический сегмент. Если вся программа размещается в одном сегменте памяти,
то эта директива указывает, что все сегментные регистры адресуют один и тот же
сегмент.
В
зависимости от используемой модели памяти в программе могут использоваться один
или несколько сегментов кода и один или несколько сегментов данных. Стековый
сегмент как правило один.
СТЕМА КОМАНД МИКРОПРОЦЕССОРА 8086
Систему
команд процессора 8086 образуют 113 базовых команд, многие из которых допускают
использование разнообразных режимов адресации.
По
функциональному назначению выделяют спедующие группы команд:
-
команды передачи данных;
-
команды арифметических операций;
-
команды логических операций и сдвигов;
-
команды передачи управления;
-
цепочечные команды;
-
команды управления микропроцессором.
КОМАНДЫ
ПЕРЕДАЧИ ДАННЫХ
Команды
передачи данных разделяют на 4 подгруппы:
-
общие команды передачи данных;
-
стековые команды;
-
команды ввода-вывода;
-
команды передачи цепочек байт или слов.
Команды
передачи данных не модифицируют состояния флажков. Исключение составляют команды
POPF и SAHF, прямо воздействующие на регистр флажков.
Далее
будут использоваться следующие обозначения: dst - получатель,
src
-
источник,
mem - адрес памяти (смещение),
заданный любым методом адресации,
reg
-
регистр общего назначения,
sreg -
сегментный регистр,
aс
-
регистр-аккумулятор (AL или AX),
data -
непосредственные данные.
ОБЩИЕ
КОМАНДЫ ПЕРЕДАЧИ ДАННЫХ
В
эту подгруппу входят команды, осуществляющие передачу регистр-регистр,
регистр-память и память-регистр. Наиболее мощной среди них является команда
MOV.
Команда MOV
Эта
команда имеет следующее обобщенное представление:
MOV dst, src
т.е.
первым указывается операнд-получатель, а вторым - операндисточник. Одним из
операндов обязательно должен быть регистр.
Команда
осуществляет передачу: регистр - регистр,
регистр
- память,
память
- регистр,
непосредственные
данные - регистр,
непосредственные
данные - память,
регистр
- сегментный регистр,
память
- сегментный регистр,
сегментный
регистр - регистр,
сегментный
регистр - память.
Допустимые
форматы команды:
MOV
mem/reg1, mem/reg2
MOV
mem/reg, data
MOV
sreg, mem/reg
MOV
mem/reg, sreg
Команда
обмена XCHG
Команда
обмена XCHG позволяет обменивать содержимое любого общего регистра и ячейки
памяти, а также любой пары общих регистров.
Формат
команды:
XCHG
reg, mem/reg
Команда XLAT
Команда
преобразования XLAT применяется для быстрого преобразования символов из
одного кода в другой. Она заменяет содержимое аккумулятора AL на байт из
256-байтовой таблицы, начальный адрес которой находится в регистре BX, а
восьмибитовое смещение - в регистре AL. В качестве сегментного используется
регистр DS.
Формат
команды:
XLAT
Команды
LEA, LDS и LES
Команды
LEA, LDS и LES предназначены для загрузки эффективного адреса.
Команда
LEA извлекает из памяти 16-битовый адрес и помещает его в один из общих
регистров. Практически эта команда дублирует один из вариантов команды MOV, но
выполняется быстрее.
Команда
LDS извлекает из памяти 32-битовый адрес и помещает первое считанное из памяти
слово в заданный общий регистр, а второе - в сегментный регистр DS.
Команда
LES извлекает из памяти 32-битовый адрес и помещает первое считанное из памяти
слово в заданный общий регистр, а второе - в сегментный регистр ES.
Обычно
в команде LDS указывается регистр SI, а в команде LES регистр DI.
Формат
команд:
LEA
reg, mem
LDS
reg, mem
LES
reg, mem
Команды LAHF и SAHF
Команда
LAHF передает младший байт регистра флажков в регистр AH, а команда SAHF
реализует обратную передачу - содержимое регистра AH передается в младший
байт регистра флажков (старший байт не изменяется).
Формат
команд:
LAHF
SAHF
СТЕКОВЫЕ КОМАНДЫ
Каждая
команда занесения данных в стек PUSH имеет соответствующую ей команду
извлечения из стека POP. Для адресации вершины стека используется стековый
указатель SP. Все стековые команды манипулируют только словами и сопровождаются
автоматической модификацией указателя стека: при включении в стек
производится декремент, а при извлечении из стека - инкремент SP.
До
выполнения стековых команд регистры SP и SS должны быть инициализированы.
Команда
PUSH включает в стек содержимое адресуемого регистра или ячейки памяти, а
команда POP извлекает содержимое вершины стека и передает его в регистр или
ячейку памяти.
Команды
POSHF и POPF предназначены для временного запоминания в стеке и
последующего восстановления из стека содержимого регистра флагов. С их помощью
можно изменять состояние флага трассировки TF, так как команд прямого
воздействия на этот флаг нет.
Формат
команд:
PUSH
mem/reg
POP mem/reg
PUSH
sreg
POP sreg
PUSHF
POPF
КОМАНДЫ ВВОДА-ВЫВОДА
Команда
ввода IN и команда вывода OUT допускают работу как с байтами, так и со словами.
Команда IN загружает данные из заданного порта в аккумулятор, а команда OUT
выполняет передачу из аккумулятора в порт. Для портов ввода-вывода в диапазоне
00-FF можно использовать прямую укороченную адресацию, а остальные порты в
диапазоне 100-FFFF можно адресовать только косвенно через регистр DX.
Формат
команд:
IN
ac,port
OUT port,ac
(прямая укороченная адресация)
IN
ac,DX
OUT DX,ac
(косвенная адресация)
КОМАНДЫ
АРИФМЕТИЧЕСКИХ ОПЕРАЦИЙ
Процессор
8086 имеет широкий набор команд, реализующих арифметические операции, что
позволяет применять его в сложных системах обработки данных.
Арифметические
операции выполняются над целыми числами четырех типов: беззнаковыми
двоичными, знаковыми двоичными, упакованными десятичными и неупакованными
десятичными. Длина чисел может быть
8 или 16 бит.
Диапазоны
чисел: беззнаковое 8-битное: 0 - 255, беззнаковое 16-битное: 0 - 65535, знаковое
8-битное: -128 - +127, знаковое 16-битное: -32768 - +32767.
Команды
арифметических операций влияют на состояние флажков OF, SF, ZF, AF, PF и
CF.
Одни
и те же команды сложения и вычитания могут использоваться для операций как
над беззнаковыми, так и знаковыми числами. Контроль над типами чисел должен
выполнять сам программист.
КОМАНДЫ СЛОЖЕНИЯ
Команда
ADD
Команда
ADD позволяет производить сложение 8- или 16-битовых двоичных чисел в режиме
регистр-регистр, регистр-память и памятьрегистр, причем адресация памяти
осуществляется в любом допустимом режиме. Общее представление команды имеет
вид
ADD dst, src
т.е.
первый операнд складывается со вторым и результат
операции
замещает
первый операнд.
Формат
команды:
ADD
mem/reg1,mem/reg2
ADD
mem/reg,data
Команда
ADC
Команда
ADC выполняет сложение с переносом: в отличие от команды ADD в операции сложения
участвует флажок CF, значение которого прибавляется к младшему биту результата
сложения операндов.
Формат
команды:
ADC
mem/reg1,mem/reg2
ADC
mem/reg,data
Команда
INC
Команда
INC позволяет увеличить на 1 содержимое любого общего регистра или ячейки
памяти.
Формат
команды:
INC
mem/reg
КОМАНДЫ
ВЫЧИТАНИЯ
Команда
SUB позволяет производить вычитание 8- или 16-битных двоичных чисел. Общее
представление команды имеет вид
SUB dst, src
т.е.
второй операнд вычитается из первого
и результат операции
замещает
первый операнд.
Формат
команды:
SUB
mem/reg1,mem/reg2
SUB
mem/reg,data
Команда
SBB
Команда
SBB выполняет вычитание с переносом: в отличие от команды SUB в операции
вычитания участвует флажок CF, значение которого вычитается из младшего бита
результата вычитания операндов.
Формат
команды:
SBB
mem/reg1,mem/reg2
SBB
mem/reg,data
Команда
DEC
Команда
DEC позволяет уменьшить на 1 содержимое любого общего регистра или ячейки
памяти.
Формат
команды:
DEC
mem/reg
Команда
NEG
Команда
NEG изменяет знак числа, находящегося в регистре или ячейке памяти, на
противоположный.
Формат
команды:
NEG
mem/reg
КОМАНДА
СРАВНЕНИЯ
Команда
сравнения CMP выполняет вычитание второго операнда из первого, но нигде не
запоминает результат операции и влияет только на состояние флажков.
Формат
команды:
CMP
mem/reg1,mem/reg2
CMP
mem/reg,data
КОМАНДЫ
УМНОЖЕНИЯ
Микропроцессор
8086 имеет две команды умножения: для беззнаковых и для знаковых двоичных
чисел. Умножение десятичных чисел требует использования специальных команд
коррекции, которые будут рассматриваться позднее.
Команда
MUL
Команда
умножения беззнаковых целых чисел MUL выполняет умножение адресуемого операнда
на содержимое аккумулятора. Общее представление команды имеет вид
MUL
src
При
операции над байтами функции аккумулятора выполняет регистр AL, а 16-битный
результат операции помещается в регистр AX. При операции над словами функции
аккумулятора выполняет регистр AX, а произведение длиной 32 бита формируется в
регистрах DX (старшее слово) и AX (младшее слово).
Формат
команды:
MUL
reg
MUL
mem
Команда IMUL
Команда
IMUL аналогична команде MUL, но сомножители и произведение интерпретируются
как знаковые двоичные числа в дополнительном коде.
Формат
команды:
IMUL
reg
IMUL
mem
КОМАНДЫ
ДЕЛЕНИЯ
Микропроцессор
8086 имеет две команды деления: для беззнаковых и для знаковых двоичных
чисел. Деление десятичных чисел также требует использования специальных команд
коррекции.
Команда
DIV
Команда
деления беззнаковых чисел DIV производит деление содержимого аккумулятора и его
расширения на содержимое адресуемого операнда.
При
делении 16-битного делимого на 8-битный делитель делимое помещают в регистр AX.
В результате выполнения операции частное формируется в регистре AL, а остаток -
в AH.
При
делении 32-битного делимого на 16-битный делитель старшая часть делимого
помещается в регистр DX, а младшая - в AX. В результате выполнения операции
частное формируется в регистре AX, а остаток - в DX.
При
делении на 0 автоматически происходит прерывание и переход к специальной
программе обработки.
Формат
команды:
DIV
reg
DIV
mem
Команда IDIV
Команда
IDIV аналогична команде DIV, но делимое, делитель и частное интерпретируются как
знаковые двоичные числа в дополнительном коде.
Формат
команды:
IDIV
reg
IDIV
mem
Команды преобразования
Команда
преобразования байта в слово CBW расширяет знак содержимого регистра AL в
регистр AH. Команда преобразования слова в двойное слово CWD передает знак
содержимого регистра AX во все биты регистра DX.
Команды
преобразования не влияют на состояния флагов.
Форматы
команд:
CBW
CWD
КОМАНДЫ
ДЕСЯТИЧНОЙ АРИФМЕТИКИ
Микропроцессор
8086 допускает два представления десятичных чисел: упакованный формат
(BCD-формат) и неупакованный (ASCII- формат). В формате BCD байт содержит две
десятичные цифры (по одной в каждой тетраде). В ASCII-формате байт содержит одну
десятичную цифру в коде ASCII. В обоих форматах многоразрядные десятичные числа
представляются последовательностями байт.
Команды
десятичной арифметики оперируют только с байтами, причем основным рабочим
регистром во всех десятичных операциях является регистр AL.
Операции
с числами в форматах BCD и ASCII выполняются в два этапа: сначала над 8-битными
операндами выполняются обычные операции двоичной арифметики, а затем
осуществляется коррекция результата. Команды коррекции являются безадресными,
так как работают с содержимым аккумулятора AL.
Команды для формата BCD
Команда
десятичной коррекции для сложения DAA выполняет коррекцию суммы, полученной
в результате выполнения команд ADD и ADC и должна следовать непосредственно за
ними.
Команда
десятичной коррекции для вычитания DAS выполняет коррекцию разности, полученной
в результате выполнения команд SUB и SBB и должна следовать непосредственно за
ними.
Форматы
команд:
DAA
DAS
Команды для формата ASCII
Команда
десятичной коррекции для сложения AAA выполняет коррекцию суммы, полученной
в результате выполнения команд ADD и ADC и должна следовать непосредственно за
ними.
Команда
десятичной коррекции для вычитания AAS выполняет коррекцию разности, полученной
в результате выполнения команд SUB и SBB и должна следовать непосредственно за
ними.
Команда
десятичной коррекции для умножения AAM выполняет коррекцию
произведения, полученного в
результате выполнения команды MUL
и должна следовать непосредственно за ней. Старший разряд результата помещается в
регистр AH, младший - в AL.
Команда
десятичной коррекции для деления AAD отличается тем, что должна выполняться
перед командой деления DIV.
Форматы
команд:
AAA
AAS
AAM
AAD
КОМАНДЫ ЛОГИЧЕСКИХ ОПЕРАЦИЙ И КОМАНДЫ СДВИГОВ
КОМАНДЫ
ЛОГИЧЕСКИХ ОПЕРАЦИЙ
Логические
операции представлены командами NOT (инверсия), AND (конъюнкция), OR
(дизъюнкция), XOR (исключающее ИЛИ) и командой TEST, которая выполняет
конъюнкцию операндов, но не изменяет их значений. Все логические операции
являются поразрядными, т.е. выполняются независимо для всех бит операндов.
Бинарные
команды AND, OR, XOR и TEST воздействуют на флажки OF, SF, ZF, PF и CF. Унарная
операция NOT не влияет на состояние флажков.
Форматы
команд:
AND
mem/reg1,mem/reg2
AND
mem/reg,data
OR
mem/reg1,mem/reg2
OR
mem/reg,data
XOR
mem/reg1,mem/reg2
XOR
mem/reg,data
TEST
mem/reg1,mem/reg2
TEST
mem/reg,data
NOT
mem/reg
КОМАНДЫ СДВИГОВ
Команды
сдвигов подразделяются на команды простых сдвигов и команды циклических сдвигов.
Циклические сдвиги влияют только на флаги OF и CF, а обычные изменяют пять
флажков: OF, SF, ZF, PF и
CF.
Команды сдвигов могут работать как с байтами, так и со словами.
Команды
ROL и ROR реализуют простой циклический сдвиг влево и вправо соответственно,
помещая значение из выдвигаемого бита в освобождающийся бит.
Команды
RCL и RCR называются командами циклического сдвига влево и вправо через перенос,
так как флажок CF расширяет сдвигаемый операнд на один бит. Таким образом,
значение из CF загружается в освобождающийся бит, а выдвигаемый бит
помещается в CF.
Команды
SHL и SHR реализуют логический сдвиг влево и вправо соответственно. Для
логического сдвига характерно, что в освобождающийся бит загружается нуль,
а выдвигаемый бит теряется.
Команды
SAL и SAR предназначены для арифметического сдвига влево и вправо.
Арифметический сдвиг вправо отличается от логического сдвига тем, что
знаковый бит не сдвигается, а дублируется в соседнем правом бите, сохраняя тем
самым знак числа. Арифметический сдвиг влево эквивалентен логическому,
поэтому мнемоники SAL и SHL обозначают одну и ту же машинную команду. Команды
арифметического сдвига по существу реализуют умножение и деление чисел без знака
на степень числа 2.
Поле
операнда команд сдвига имеет вид mem/reg,count. Опреанд count определяет число
сдвигов и может быть указан как константа 1 или как регистр CL. В первом
случае выполняется сдвиг на один бит, а во втором число сдвигов определяется
содержимым регистра CL, которое воспринимается как беззнаковое число.
Формат
команды:
ROL mem/reg,1
ROL
mem/reg,CL
ROR mem/reg,1
ROR
mem/reg,CL
RCL mem/reg,1
RCL
mem/reg,CL
RCR mem/reg,1
RCR
mem/reg,CL
SHL mem/reg,1
SHL
mem/reg,CL
SHR mem/reg,1
SHR
mem/reg,CL
SAL mem/reg,1
SAL
mem/reg,CL
SAR mem/reg,1
SAR
mem/reg,CL
КОМАНДЫ
ПЕРЕДАЧИ УПРАВЛЕНИЯ
Сегментная
организация программной памяти определяет две основные разновидности команд
передачи управления. Передача управления в пределах текущего сегмента кода
называется внутрисегментной - при этом модифицируется только регистр IP и
адрес перехода может быть представлен одним словом. Такая передача управления
называется ближней (тип NEAR), а ее вариант с сокращеннным диапазоном
адресов переходов - короткой. Передача управления за пределы текущего
сегмента кода называется межсегментной или дальней (тип FAR) - при этом
необходимо модифицировать содержимое регистров IP и CS и адрес перехода
представляется двумя словами (сегмент:смещение).
Команды
передачи управления процессора 8086 подразделяются на команды безусловных
переходов, условных переходов, вызовов, возвратов, управления циклами и команды
прерываний.
Команды
передачи управления не изменяет состояние регистра флагов (за исключением
команды IRET).
КОМАНДЫ
БЕЗУСЛОВНЫХ ПЕРЕХОДОВ
Команды
безусловного перехода имеют общую мнемонику JMP. Команда короткого безусловного
перехода содержит во втором байте смещение, которое интерпретируется как
знаковое целое. Диапазон значений байта смещения составляет -128 - +127. Если
смещение положительное, осуществляется переход вперед, а если отрицательное
- переход назад.
Команда
ближнего безусловного перехода может либо непосредственно содержать
16-битное смещение, либо косвенный адрес 16-битного смещения. Диапазон смещения
составляет -32768 - +32767 байт относительно адреса команды, находящейся после
команды JMP.
Команда
дальнего безусловного перехода
реализует прямой и
косвенный
межсегментнные переходы.
Форматы
команд:
JMP
dispL
- короткий переход
JMP
disp
- ближний прямой переход
JMP
mem/reg - ближний косвенный
переход
JMP
addr
- дальний прямой переход
JMP
mem
- дальний косвенный переход
КОМАНДЫ УСЛОВНЫХ ПЕРЕХОДОВ
В
системе команд процессора 8086 имеется 19 двухбайтных команд условных переходов.
При выполнении этих команд анализируется некоторое условие, закодированное
текущими состояниями флагов, и если оно выполняется, то осуществляется
переход, а если нет, то выполняется следующая по побядку команда.
Все
условные переходы являются короткими. Некоторые команды для удобства
программирования могут иметь несколько различных мнемонических обозначения.
Мнемонические
обозначения команд:
1)
Команды для работы с беззнаковыми числами: JA/JNBE - переход, если больше; JAE/JNB/JNC - переход, если больше или равно;
JB/JNAE/JC - переход, если меньше; JBE/JNA - переход, если меньше или равно.
2)
Команды для работы со знаковыми числами: JG/JNLE -
переход, если больше; JGE/JNL
- переход, если больше или
равно; JL/JNGE - переход, если меньше; JLE/JNG -
переход, если меньше или равно; JNS - переход, если больше нуля; JS - переход, если меньше нуля.
3)
Команды, общие для знаковых и беззнаковых чисел: JE/JZ - переход, если равно /
переход, если ноль; JNE/JNZ - переход, если не равно / переход, если не
ноль;
JNO - переход, если нет переполнения;
JO - переход, по переполнению.
4)
Прочие команды:
JCXZ
- переход, если содержимое
регистра CX равно нулю;
JNP/JPO -
переход при отсутствии четности;
JP/JPE - переход по четности.
Форматы
команд такие же, как у короткого безусловного перехода.
КОМАНДЫ ВЫЗОВОВА ПОДПРОГРАММ
Команда
вызова подпрограммы CALL передает управление с автоматическим сохранением
адреса возврата в стеке. В поле операнда этой команды находится метка первой
команды вызываемой подпрог-
раммы.
При
переходе к подпрограмме необходимо временно запомнить адрес команды, находящейся
после команды CALL. Этот адрес называется адресом возврата. После того, как
подпрограмма закончит свои действия, завершающая ее команда возврата RET
передает управление по запомненному адресу возврата. Адрес возврата запоминается
в стеке.
Вызовы
могут быть внутрисегментными (тип NEAR) или межсегментными (тип FAR). В
первом случае вызываемая подпрограмма находится в текущем сегменте кода, а во
втором - в произвольном.
Команды
внутрисегментного перехода производят декремент SP на 2, включают в стек
содержимое IP, а затем прибавляют к IP 16-битное смещение, которое
интерпретируется как знаковое целое.
Команды
межсегментного перехода производят декремент SP на 2, включают в стек содержимое
CS, снова производят декремент SP на 2, включают в стек содержимое IP, затем в
IP загружается значение смещения, а в CS - сегментный адрес.
Формат
команды:
CALL
disp
- непосредственный ближний вызов;
CALL
mem/reg - косвенный ближний вызов;
CALL
addr
- непосредственный дальний вызов;
CALL
mem
- косвенный дальний вызов.
КОМАНДЫ ВОЗВРАТА ИЗ ПОДПРОГРАММ
Каждая
подпрограмма должна содержать минимум одну команду возврата RET, которая
возвращает управление вызывающей программе. Такая передача управления
осуществляется путем извлечения из стека адреса возврата, включенного в него
командой вызова подпрограммы.
Команды
внутрисегментного и межсегментного возврата имеют одну и ту же мнемонику RET.
Тип команды, соответствующей этой мнемонике, определяется ассемблером
автоматически.
Формат
команды:
RET
- однобайтный вариант,
RET
data - трехбайтный вариант.
Однобайтная
команда RET с кодом операции C3 реализует внутрисегментный возврат. Она
передает слово из вершины стека в IP и увеличивает SP на 2.
Однобайтная
команда RET с кодом операции CB осуществляет межсегментный возврат. Она передает
слово из вершины стека в IP, увеличивает SP на 2. передает слово из вершины
стека в CS и снова увеличивает SP на 2.
Трехбайтные
варианты команд возврата осуществляют те же действия, что и однобайтные, а затем
прибавляют содержащиеся в них данные к указателю стека. Эти команды
предназначены для упрощения возврата из тех подпрограмм, параметры которых
передаются в стеке. Прибавление к SP данных из RET эквивалентно удалению пара-
метров
из стека.
КОМАНДЫ УПРАВЛЕНИЯ ЦИКЛАМИ
Три
команды управления циклами применяются для организации программных циклов. В них
предусматривается использование регистра CX в качестве счетчика цикла.
В
поле операнда команд управления циклами находится метка первой команды цикла
(8-битовое смещение). Диапазон переходов этих команд составляет -128 - +127 байт
от следующей команды.
Команда
LOOP производит декремент регистра CX и, если содержимое CX не равно нулю,
происходит переход к началу цикла. В противном случае выполняется следующая по
порядку команда.
Мнемоники
LOOPE/LOOPZ определяют одну и ту же машинную команду, которая производит
декремент регистра CX, а затем передает управление в начало цикла, если
содержимое CX не равно нулю и ZF=1. В противном случае выполняется следующая по
порядку команда.
Мнемоники
LOOPNE/LOOPNZ также определяют одну и ту же машинную команду, которая
производит декремент регистра CX, а затем передает управление в начало цикла,
если содержимое CX не равно нулю и ZF=0. В противном случае выполняется
следующая по порядку команда.
КОМАНДЫ ПРЕРЫВАНИЙ
В
процессоре 8086 имеются 3 команды, относящиеся к прерываниям.
Команда
программного прерывания INT вызывает программу обработки, определяемую
типом прерывания.
Формат
команды:
INT
type - вызов прерывания с номером type (от 0 до 255),
INT
- вызов прерывания контрольного останова (номер 3).
Команда
INT выполняется следующим образом:
1)
декремент указателя стека на 2;
2)
включение в стек содержимого регистра флажков;
3)
сброс флажков IF и TF;
4)
декремент указателя стека на 2;
5)
включение в стек содержимого регистра CS;
6)
определение адреса вектора прерывания ADDRESS путем умножения кода типа
прерывания на 4;
7)
загрузка в регистр CS слова памяти, расположенного по адресу ADDRESS+2;
8)
декремент указателя стека на 2;
9)
включение в стек содержимого IP;
10)
загрузка в регистр IP слова памяти, расположенного по адресу ADDRESS.
В
результате этих действий осуществляется межсегментный кос-
венный
вызов подпрограммы обработки прерывания.
Команда
прерывания при переполнении INTO генерирует программное прерывание только в
том случае, если установлен флаг переполнения. Она вызывает прерывание с номером
4.
Формат
команды:
INTO
Команда
возврата из прерывания IRET предназначена для выхода из подпрограммы обработки
прерываний, инициированной аппаратно или программно.
Команда
IRET выполняется следующим образом:
1)
слово из вершины стека передается в IP;
2)
производится инкремент SP на 2;
3)
слово из вершины стека передается в CS;
4)
производится инкремент SP на 2;
5)
слово из вершины стека передается в регистр флагов;
6)
производится инкремент SP на 2.
Формат
команды:
IRET
ЦЕПОЧЕЧНЫЕ КОМАНДЫ
Под
цепочкой понимается последовательность любых контекстно связанных байт или слов,
находящихся в смежных ячейках памяти.
В
системе команд процессора 8086 имеется 5 команд, предназначенных для
обработки одного элемента цепочки. Цепочечной команде может предшествовать
специальный однобайтный префикс повторения REP, который вызывает повторение
действия команды над следующими элементами цепочки. Повторение расчитано на
максимальную длину цепочек 64 Кбайт и выполняется значительно быстрее цикла
LOOP.
Цепочечные
команды могут иметь операнд-источник, операндполучатель или и то и другое
одновременно. Подразумевается, что цепочка-источник по умолчанию находится в
текущем сегменте данных, но допускается префикс замены сегмента.
Цепочка-получатель может находиться только в текущем дополнительном сегменте.
При этом содержимое регистра SI всегда считается смещением текущего элемента
цепочки-источника, а содержимое регистра DI - смещением текущего элемента
цепочки-получателя.
Необходимые
в команде индексные и сегментные регистры должны быть инициализированы до ее
выполнения.
При
выполнении цепочечной команды содержимое регистров SI и DI автоматически
изменяется, чтобы адресовать следующие элементы цепочек. Флаг направления DF
определяет автоинкремент (DF=0) или автодекремент индексных регистров.
Если
команде предшествует префикс повторения, то после каждого ее выполнения
производится декремент регистра-счетчика CX, поэтому его необходимо
предварительно инициализировать на
требуемое
число повторений. Когда содержимое
CX достигает нуля,
управление
передается следующей команде.
Префикс повторения
Префикс
повторения имеет 5 мнемокодов: REP, REPE, REPZ, REPNE, REPNZ.
Префикс
REP используется с командами MOVS и STOS и вызывает повторение операции до тех
пор, пока содержимое CX не равно 0.
Префиксы
REPE и REPZ соответствуют тому же коду команды, что и мнемоника REP, но
используются совместно с командами CMPS и SCAS. Они вызывают повторение операции
до тех пор, пока ZF=1 и содержимое CX не равно 0.
Префиксы
REPNE и REPNZ соответствуют одному коду команды, и используются совместно с
командами CMPS и SCAS. Они вызывают повторение операции до тех пор, пока ZF=0 и
содержимое CX не равно 0.
Команда MOVS
Команда
MOVS передает байт или слово из цепочки, адресуемой регистром SI, в цепочку,
адресуемую регистром DI. Команда передачи цепочки байт MOVSB после пердачи
байта увеличивает содержимое регистров SI и DI на 1, а команда передачи цепочки
слов MOVSW после передачи слова увеличивает их содержимое на 2.
Формат
команды:
MOWSB
MOVSW
Команда CMPS
Команда
сравнения цепочек CMPS производит вычитание байта или слово цепочки, адресуемой
регистром DI, из байта или слова цепочки, адресуемой регистром SI. В зависимости
от результата вычитания устанавливаются флаги, но сами операнды не изменяются.
Команда сравнения цепочек байт CMPSB после каждой операции сравнения
увеличивает содержимое регистров SI и DI на 1, а команда сравнения цепочек слов
CMPSW - на 2.
Формат
команды:
CMPSB
CMPSW
Команда SCAS
Команда
сканирования цепочки SCAS вычитает элементы цепочки, адресуемой регистром DI, из
содержимого аккумулятора AL (при работе с байтами) или AX (при работе со
словами). В зависимости от результата вычитания устанавливаются флаги, но сами
операнды
не
изменяются. Команда сканирования цепочки байт SCASB после каждой операции
сканирования увеличивает содержимое регистра DI на 1, а команда сканирования
цепочки слов SCASW - на 2.
Формат
команды:
SCASB
SCASW
Команда LODS
Команда
загрузки цепочки в аккумулятор LODS загружает элементы цепочки, адресуемой
регистром SI, в аккумулятор AL или AX. Команда загрузки цепочки байт LODSB после
выполнения каждой операции увеличивает содержимое регистра SI на 1, а
команда загрузки цепочки слов LODSW - на 2.
Формат
команды:
LODSB
LODSW
Команда STOS
Команда
запоминания содержимого аккумулятора в цепочке STOS передает содержимое
аккумулятора в элемент цепочки, адресуемый регистром DI. Команда запоманания
цепочки байт STOSB после выполнения каждой операции увеличивает содержимое
регистра DI на 1, а команда запоминания цепочки слов STOSW - на 2.
Формат
команды:
STOSB
STOSW
КОМАНДЫ УПРАВЛЕНИЯ МИКРОПРОЦЕССОРОМ
Команды
данной группы обеспечивают программное управление различными функциями
процессора. Они делятся на две подгруппы: команды установки флагов и команды
синхронизации.
|