- •1. Предварительные сведения 6
- •2. Процессоры intel в реальном режиме 11
- •3. Директивы и операторы ассемблера 51
- •Введение
- •1. Предварительные сведения
- •1.1. Подготовка программ на языке ассемблера
- •1.2. Представление данных в компьютерах
- •1.2.1. Двоичная система счисления
- •1.2.2. Биты, байты и слова
- •1.2.3. Шестнадцатеричная система счисления
- •1.2.4. Числа со знаком
- •1.2.5. Логические операции
- •1.2.6. Коды символов
- •2. Процессоры intel в реальном режиме
- •2.1. Регистры процессора
- •2.1.1. Регистры общего назначения
- •2.1.2. Модели памяти и сегментные регистры
- •2.1.3. Стек
- •2.1.4. Регистр флагов
- •2.2.4. Косвенная адресация
- •2.2.5. Адресация по базе со смещением
- •2.2.6. Косвенная адресация с масштабированием
- •2.2.7. Адресация по базе с индексированием
- •2.2.8. Адресация по базе с индексированием и масштабированием
- •2.3. Основные непривилегированные команды
- •2.3.1. Пересылка данных
- •2.3.2. Двоичная арифметика
- •2.3.3. Десятичная арифметика
- •2.3.4. Логические операции
- •2.3.5. Сдвиговые операции
- •2.3.6. Операции над битами и байтами
- •2.3.7. Команды передачи управления
- •2.3.8. Строковые операции
- •2.3.9. Управление флагами
- •2.3.10. Загрузка сегментных регистров
- •2.3.11. Другие команды
- •3. Директивы и операторы ассемблера
- •3.1. Структура программы
- •3.2. Директивы распределения памяти
- •3.2.1. Псевдокоманды определения переменных
- •3.2.2. Структуры
- •3.3. Организация программы
- •3.3.1. Сегменты
- •3.3.2. Модели памяти и упрощенные директивы определения сегментов
- •3.3.4. Процедуры
- •3.3.5. Конец программы
- •3.3.6. Директивы задания набора допустимых команд
- •3.3.7. Директивы управления программным счетчиком
- •3.3.8. Глобальные объявления
- •3.3.9. Условное ассемблирование
- •3.4. Выражения
- •3.5. Макроопределения
- •3.5.1. Блоки повторений
- •3.5.2. Макрооператоры
- •3.5.3. Другие директивы, используемые в макроопределениях
- •3.6. Другие директивы
- •3.6.1. Управление файлами
- •3.6.2. Управление листингом
- •3.6.3. Комментарии
- •Литература
3.3.9. Условное ассемблирование
В языке ассемблера, как и во многих других языках программирования, присутствуют средства, позволяющие игнорировать тот или иной участок программы в зависимости от выполнения условий.
if выражение
. . .
endif
Если значение выражения — ноль (ложь), весь участок программы между IF и ENDIF игнорируется. Директива IF может также сочетаться с ELSE и ELSEIF:
if выражение
. . .
else
. . .
endif
Если значение выражения — ноль, ассемблируется участок программы от ELSE до ENDIF, иначе — от IF до ELSE.
if выражение1
. . .
elseif выражение2
. . .
elself выражениеЗ
. . .
else
. . .
endif
В этом случае, если, например, выражение 2 не равно нулю, будет ассемблироваться участок программы между первой и второй директивой ELSEIF. Если все три выражения равны нулю, ассемблируется фрагмент от ELSE до ENDIF. Такая структура директив может использоваться в частном случае аналогично операторам switch/case языков высокого уровня, если выражения — проверки некоторой константы на равенство.
Иногда директивы условного ассемблирования используются для того, чтобы прервать ассемблирование программы, если обнаружилась какая-нибудь ошибка. Для этих случаев предназначены директивы условной генерации ошибок.
if $ gt 65535 ; если адрес вышел за пределы сегмента
.err
endif
Встретив директиву .ERR, ассемблер прекратит работу с сообщением об ошибке.
3.4. Выражения
При описании многих директив ассемблера использовались выражения. Выражение — это набор чисел, меток, или строк, связанных друг с другом операторами. Например: 2 + 2 — выражение, состоящее из двух чисел (2 и 2) и оператора «+». Каждое выражение имеет значение, которое определяется как результат действия операторов: так, значение выражения 2 + 2 — число 4. Все выражения вычисляются в ходе ассемблирования программы, так что в полученном коде используются только значения.
Оператор «<>» (угловые скобки). Часть выражения, заключенная в угловые скобки, не вычисляется, а используется как строка символов, например:
message1 equ <foobar>
Оператор «()» (круглые скобки). Часть выражения, заключенная в круглые скобки, вычисляется в первую очередь.
mov аl, 2(3+4) ; mov al, 14
Арифметические операторы: «+» (плюс), «–» (минус), «» (умножение), «/» (целочисленное деление), MOD (остаток от деления). Эти операторы выполняют соответствующие арифметические действия.
mov al, 90 mod 7 ; mov al, 6
Кроме того, к арифметическим операторам относится унарный минус — минус, который ставят перед отрицательным числом.
Логические операторы: AND (И), NOT (HE), OR (ИЛИ), XOR (исключающее ИЛИ), SHL (сдвиг влево), SHR (сдвиг вправо). Эти операторы выполняют соответствующие логические действия.
mov ax,1234h AND 4321h ; mov ax, 0220h
Операторы сравнения: EQ (равно), GЕ (больше или равно), GT (больше), LE (меньше или равно), LT (меньше), NE (не равно). Результат действия каждого из этих операторов — единица, если условие выполняется, и ноль — если не выполняется.
errnz $ gt 65535 ; если адрес больше 64 килобайт – ошибка
Операторы адресации:
SEG выражение — сегментный адрес.
OFFSET выражение — смещение.
THIS тип — текущий адрес (MASM и TASM).
Тип PTR выражение — переопределение тина.
LARGE выражение — 32-битное смещение (TASM).
SMALL выражение — 16-битное смещение (TASM).
SHORT выражение — 8-битное смещение.
SEG и OFFSET возвращают соответствующую часть адреса своего аргумента:
mov dx, offset msg ; занести в DX смещение переменной msg
THIS создает операнд, адресом которого является текущее значение счетчика:
mov al, this byte–1 ; занести в AX последний байт кода предыдущей команды
PTR создает аргумент, адресом которого является значение выражения, а тип указан явно:
mov dword ptr [si], 0 ; записать 4 байта нулей по адресу DS:SI
LARGE, SMALL и SHORT используются с командами передачи управления, если возникают двусмысленности при косвенных переходах:
jmp larqe dword ptr old_address ; переменная old_address содержит
; 32-битное смещение
jmp small dword ptr old_address ; переменная old_address содержит
; 16-битный сегментный адрес и
; 16-битное смещение
jmp short short_label ; метка short_label находится ближе,
; чем +128/-127 байт от этой команды, так что
; можно использовать короткую форму команды JMP
Другие операторы:
. (точка) — ссылка на элемент структуры.
: (двоеточие) — переопределение сегмента.
[] (квадратные скобки) — косвенная адресация.
? — неинициализированное значение.
Число DUP (значение) — повторяющееся значение.
Эти пять операторов были описаны ранее, когда говорилось о структурах данных, методах адресации и псевдокомандах определения данных.
LENGTH метка — число элементов данных
baz dw 0,1,2,3,4,5,6,7 ; определить таблицу из 8 слов
baz_count = length table ; table_count = 8
SIZE метка — размер данных
baz_size = size table ; table_size = 16
