- •1.1.1. Кодирование символов
- •2. Системный отладчик Debug
- •2.1. Адресация памяти
- •2.2. Работа в отладчике
- •Лабораторная работа № 1
- •3. Основы программирования
- •3.1. Процесс программирования
- •3.1.1. Этапы создания программы
- •3.1.2. Компиляция программы. Опции командной строки
- •3.2. Cинтаксис ассемблерной программы
- •3.3. Простейшая программа
- •3.4. Скелет (каркас) программы
- •3.4.1. Модуль EXE
- •3.4.2. Модуль COM
- •3.5. Образ программы в памяти
- •3.5.1. Модуль EXE
- •3.5.2. Модуль COM
- •3.6. Работа с отладчиком Turbo Debugger (TD)
- •Лабораторная работа №1
- •4. Операторы и директивы
- •4.1. "Препроцессорные" директивы INCLUDE и EQU
- •4.2. Директивы описания и инициализации переменных DB, DW и DD
- •4.2.1. Директива DB (Define Byte - определить байт)
- •4.2.2. Директивы DW и DD (Define Word и Define Double Word)
- •4.3. Операторы Assembler
- •4.3.1. Операторы обработки данных
- •4.3.2. Операторы передачи управления
- •4.4. Вспомогательные псевдооператоры
- •4.5. Работа с макрооператорами
- •Лабораторная работа № 2
- •4.6. Приложение к лабораторной работе № 2. Адресация
- •4.6.1. Форматы машинных команд и их кодирование
- •4.6.2. 16-битный режим адресации операндов в памяти
- •5. Сервисные функции DOS
- •5.1.1. Ввод с клавиатуры символьной информации
- •5.1.2. Системные функции DOS ввода данных с клавиатуры
- •5.1.3. Команды работы со строками
- •5.1.4. Системные функции DOS вывода данных
- •Лабораторная работа №3
- •Лабораторная работа №4
- •6. Функции BIOS для работы с экраном и клавиатурой
- •6.1. Прямое программирование видеобуфера в текстовом режиме
- •6.2. Прерывание 10h. Видеофункции BIOS
- •6.3. Прерывания 16h, 1Ah, 15h
- •6.3.1. Прерывание 16h
- •6.3.2. Прерывание 1Ah
- •6.3.3. Прерывание 15h
- •Лабораторная работа №5
- •Заключение
- •Рекомендуемая литература
- •Использованная литература
4.3.2. Операторы передачи управления
Операторы передачи управления делятся на:
1.Операторы условных переходов;
2.Операторы безусловных переходов;
3.Операторы циклов;
4.Операторы процедур;
5.Операторы прерываний;
6.Операторы останова и холостого хода.
Операторы условных переходов
Формат оператора условного перехода: КОП а
Где а - метка, или метка + (-) выражение, вычисление которого дает константу. Операнд а указывает на тот оператор в программе, на который делается переход в случае выполнения предусмотренных в операторе перехода условий. Такими условиями являются значения одного, двух или трех флажков.
Машинная инструкция, соответствующая оператору условного перехода, имеет длину 2 байта. В первом байте находится КОП, а во втором - "расстояние" между содержимым IP и искомым адресом. Это «расстояние» есть число со знаком, т.к. переходы могут делаться как вперед по программе, так и назад.
Водном байте можно разместить число со знаком (в дополнительном коде) от -128 до +127, Это приводит к тому, что оператор условного перехода может использоваться лишь для небольших переходов. Для выполнения больших переходов, в том числе и в другие программные сегменты, оператор данного типа дополняется операторами безусловного перехода.
Пример:
Подсчитаем содержимое второго байта в операторе перехода в следующем фрагменте: 0050 Again: INC CX
0052 ADD AX, [BX]
0054 JZ Again
0056 Next: MOV Result, CX
Вмомент выполнения JZ (IP)=0056h. Следовательно, второй байт JZ должен содержать -6. В дополнительном коде это FAh.
Некоторые операторы условного перехода:
3.JZ (или JE) - перейти, если нуль или равно. Условием перехода является: ZF=1;
4.JNZ (или JNE) - перейти, если не нуль или не равно. Условие перехода: ZF = 0; Следующие операторы перехода записывают в программу только после операторов,
выполняющих действие над беззнаковыми данными. Эти операторы перехода не учитывают ни флаг знака SF ни флаг переполнения OF. Для них важен флаг переноса CF:
5.JA (или JNBE) - перейти, если больше, Условие: (CF = 0) & (ZF = 0);
6.JAE (или JNB) - перейти, если больше или равно, Условие: CF = 0;
7.JB (или JNAE) - перейти, если меньше. Условие: CF = 1;
8.JBE (или JNA) - перейти, если не больше. Условие: (CF = 1) V (ZF = 1).
59
Следующие операторы перехода записывают в программу только после операторов, выполняющих действия над знаковыми данными. Для них важны флаг знака SF и флаг переполнения OF:
9.JG (или JNLE) - перейти, если больше. Условие: (SF = OF)&(ZF = 0);
10.JGE (или JNL) - перейти, если больше или равно. Условие: SF = OF;
11.JL (или JNGE) - перейти, если меньше. Условие: SFне равно OF;
12.JLE(mm JNG) - перейти, если меньше или равно. Условие: (SF не равно OF)V(ZF=1). Каждому условному оператору перехода соответствует противоположный по смыслу
оператор.
Операторы безусловных переходов
Такой оператор заставляет ЦП извлечь новую инструкцию не из следующей ячейки ОП, а из какой-то другой, известной еще до начала выполнения программы. Существуют пять машинных инструкций безусловных переходов. Все они имеют одну и ту же ассемблерную мнемонику JMP и один операнд. Это:
4.внутрисегментный прямой короткий переход;
5.внутрисегментный прямой переход;
6.внутрисегментный косвенный переход;
7.межсегментный прямой переход;
8.межсегментный косвенный переход.
Во внутрисегментном переходе оператор перехода находится в том же сегменте, что
иоператор, на который делается переход. А в межсегментном переходе - в разных сегментах.
В операторах прямого перехода операндом является метка того оператора, на который делается переход. При внутрисегментном переходе данная метка имеет тип NEAR (близкий). Этот тип задается путем записи после метки символа «:». При межсегментном переходе метка перехода имеет тип FAR (дальний).
Внутрисегментный прямой короткий переход используется для переходов от +127 до -127 байтов. Инструкция перехода имеет длину 2 байта. В первом байте КОП, а во втором число со знаком, представляющее собой «расстояние» до искомого оператора. Это число идентично соответствующему числу в операторе условного перехода.
Для указания транслятору, что переход короткий, используется слово SHORT. Например.
JMP SHORT А90 A90:
Если внутрисегментный переход не короткий, слово SHORT опускается. Машинная инструкция в этом случае занимает 3 байта - один для КОП и 2 -для "расстояния" перехода.
Если переход в программе осуществляется "назад", то слово SHORT можно не писать вовсе. Т.к. при записи инструкции JMP транслятор уже «знает» расстояние до искомого оператора. При переходе вперед это расстояние транслятору неизвестно и при отсутствии слова SHORT он всегда записывает трехбайтовую инструкцию перехода.
Внутрисегментный косвенный переход задается путем записи в качестве операнда оператора JMP не метки, а адреса данных. По этому адресу (в регистре или в слове ОП) записано требуемое содержимое ЕР. Допустим, имеется оператор: JMP ВХ
60
Если в момент исполнения соответствующей машинной инструкции (ВХ) = 1ABh, то ЦП запишет в IP это число 1АВh и извлечет следующую машинную инструкцию из ОП по физическому адресу (CS)xl6+lABh.
Операторы циклов
Цикл - многократное повторение группы операторов, называемых телом цикла, до тех пор, пока выполняется некоторое условие.
Типичное условие цикла: повторить тело цикла заданное число раз. Число повторений обычно заносится в регистр СХ. Реализация такого цикла с помощью условного оператора JNZ:
Рис. 2.9. Организация цикла с помощью оператора условного перехода
Это же самое можно сделать с помощью специального оператора цикла LOOP:
Рис. 2.10. Организация цикла с помощью оператора LOOP
Рис. 2.11. Блок схема алгоритма оператора цикла
Оператор LOOP уменьшает содержимое регистра СХ на 1 и выполняет переход, если (СХ)≠0. Следующий фрагмент программы выполняет сложение М слов, начинающихся с адреса Array. Результат записывается в слово с именем Total:
MOV СХ, М
MOV АХ, 0
61
MOV SI, АХ
Lbl: ADD АХ, Array[SI]
ADD SI, 2 ; Инкремент индекса на 2 LOOP Lbl
MOV Total, АХ
Существуют еще два оператора циклов - LOOPZ (или LOOPE) и LOOPNZ (или LOOPNE). Условием повторения для LOOPZ является (СХ)≠0&ZF=1 . Т.е. кроме ненулевого содержимого счетчика СХ требуется, чтобы был установлен флаг нуля. Условием повторения для LOOPNZ является (СХ)≠0&ZF=0. Подобный оператор обычно используется для поиска в массиве заданного элемента.
Пример. Пусть метка ASCII присвоена первой ячейке массива из L символов. Требуется найти в этом массиве пробел (код ASCII пробела - 20h). Если пробела нет, требуется перейти на оператор с меткой Not.
Соответствующий фрагмент программы: MOV СХ, L
MOV SI, -1 ; Инициализировать индекс MOV AL,20h ; Код пробела -> AL Next: INC SI ; Инкремент индекса
CMP AL, ASCII[SI] ; Проверка на пробел LOOPNE Next ; Если не пробел, то цикл JNZ Not
Машинная инструкция, соответствующая оператору цикла, имеет длину 2 байта. В первом байте находится КОП, а во втором - "расстояние" до инструкции, помеченной меткой перехода. Подобно инструкции условного перехода это "расстояние" может находиться в пределах от -128 до +127 байт.
Операторы процедур
Процедура - это список инструкций, который можно вызывать из различных мест программы. Переход к процедуре называется вызовом, а соответствующий переход назад называется возвратом. Вызов процедуры выполняет инструкция CALL а, где а - адрес, по которому находится первая инструкция процедуры. Возврат осуществляет инструкция RET. Возврат после каждого вызова осуществляется к инструкции, которая находится в памяти сразу за инструкцией CALL .
Основное отличие оператора CALL от соответствующей инструкции заключается в том, что в качестве операнда записывается не адрес первой инструкции процедуры, а его заменитель - имя (метка) процедуры. Пример:
CALL Readhex где Readhex - имя процедуры.
Для задания имени процедуры используется псевдооператор PROC, которому всегда соответствует псевдооператор ENDP, записываемый в конце процедуры, например:
Readhex PROC NEAR
....................................... ; Операторы процедуры RET ; Возврат из процедуры
Readhex ENDP
62