СОДЕРЖАНИЕ
2. Программная модель микропроцессора 8086
2.4. Способы задания операндов команды
3. Основные понятия языка ассемблера
3.2. Директивы определения данных
4. Сегментированная модель памяти
4.3. Общая структура программы
5.1. Соглашению по описанию команд
5.6. Команды организации циклов
5.11. Команды управления микропроцессором
7. Разработка одномодульной программы
7.1. Трансляция и компоновка программы
8. Разработка многомодульных программ
8.1. Принципы разработки модулей
8.2. Расширенное применение директивы сегментации
Программирование микропроцессорных устройств
10. Программирование системного таймера
10.1. Описание таймера-счетчика 8254
10.3. Структура регистров таймера
11. Программирование контроллера прерываний
11.1. Механизм обработки прерываний
11.4. Контроллер прерываний 8259
11.5. Идентификация прерываний
11.6. Прерывания bios и ms-dos
12. Программирование параллельного порта
12.2. Работа с параллельным портом на низком уровне
12.3. Стандартные средства работы с параллельным портом
13. Программирование последовательного порта
13.1. Основы последовательной передачи данных
13.2. Последовательный интерфейс rs-232c
13.3. Универсальный асинхронный приемо-передатчик 8250
13.4. Порты асинхронного адаптера
13.5. Стандартные средства программирования последовательного порта
В качестве операнда директивы DW может быть указано адресное выражение, т.е. выражение, значением которого является адрес:
A DB?
B DW A
В примере ассемблер запишет в слово, выделенное, под переменную B, адрес переменной A, который становится начальным значением переменной B.
В правой части директивы DW можно указать любое число операндов, а также конструкцию повторения:
A DW 100, 3 DUP(?)
Директива DD(DefineDoubleWord, определить двойное слово) определяет переменную, под которую отводится двойное слово. Переменная имеет тип DWORD (значением константы является число 4).
Определение неинициализированной переменной:
A DD ?
Под переменную А выделяется двойное слово и переменная А не получает начального значения.
Операндом директивы может быть константное выражение со значение от -231до 232-1.
B DD123456h
Переменная В получает начальное значение, причем это значение ассемблер записывает в память в обратном порядке.
Операндом директивы может быть число в диапазоне от -215до 216-1. Все выражения вычисляются в области 16-битовых чисел (по модулю 216). Например, по директиве:
A DD 8000h+8002h
начальным значением переменной A будет число 2, а не число 10002h.
В качестве операнда директивы DD может быть указано адресное выражение. В этом случае операнд определяет абсолютный адрес.
Конструкция повторения DUP:
DW 10 DUP(?), 12345h
Директива эквивалентности EQU(Equal, равно) позволяет определить константу и имеет следующий синтаксис:
<имя> EQU <операнд>
Директива аналогична описанию константы в языке Паскаль. Она определяет, что операнду дается имя, и требует, чтобы все вхождения имени в текст программы ассемблер заменял на этот операнд. Директива EQU носит информационный характер, по ней ассемблер ничего не записывает в машинную программу. Поэтому директиву EQU можно использовать в любом месте программы.
Если в правой части директивы указано имя регистра, переменной или константы, тогда имя слева объявляется синонимом данного имени и все последующие вхождения в текст программы этого имени-синонима ассемблер будет заменять на имя, указанное справа, например:
A DW ?
В EQU A
C DW В ; эквивалентно С DW A
Имена-синонимы обычно используются для введения обозначений. Например, если регистр аккумулятора используется для хранения суммы, то его можно обозначить как SUM:
SUMEQUAX
и далее использовать более наглядное имя.
Операндом директивы EQU может быть константное выражение, например:
N EQU 100
К EQU 2*N-1
Если в правой части директивы EQU находится константное выражение, тогда указанное слева имя принято называть именем константы. Значением такой константы объявляется значение выражения. Например, N – константа со значением 100, К – со значением 199. Все последующие вхождения в текст имени константы ассемблер будет заменять на значение этой константы.
Операндом может быть любой текст:
s EQU'Ошибка’
Именно на этот текст будет заменяться каждое вхождение данного имени в программу. Такой вариант директивы EQU обычно используется, чтобы ввести более короткие обозначения для часто встречающихся длинных текстов.
Директива присваиванияопределяет константу с именем, указанным в левой части и с числовым значением, равным значению выражения справа:
<имя> = <константное выражение>
В отличие от констант, определяемых по директиве EQU, константа может менять свое значение, обозначая в разных частях текста программы разные числа. По директиве присваивания можно определить только числовую константу, например:
C=10
A DW C ; эквивалентно A DW 10
C=C+2
В DB C ; эквивалентно В DB 12
В языке ассемблера выраженияделятся на два класса –константныеиадресные. Значением константного выражения является целое число, а значением адресного выражения – адрес. Адрес тоже является целым числом (порядковый номер ячейки в памяти), но рассматривается как самостоятельный тип данных.
Константные выражения.Значениями константных выражений являются 16-битовые целые. К простейшим константным выражениям относятся:
число в диапазоне от -215до 216-1 (числа вне диапазона рассматриваются как ошибка);
символ (значением выражения является код символа);
строка из двух символов (значением является число-слово, составленное из кодов этих символов);
имя константы (значением выражения является значение константы).
Среди константных операторов (операторов с числовым значением) отметим оператор TYPE и арифметические операторы (k, k1 и k2 означают константные выражения):
одноместные плюс и минус: +k, -k;
операторы сложения и вычитания: k1+k2, k1-k2;
операторы умножения и деления: k1*k2, k1/k2, k1 MOD k2 (* – умножение, / – целочисленное деление, MOD – взятие остатка от деления).
В следующем примере используется константное выражение с арифметическими операторами:
К EQU 30
X DB (3*К-1)/2 DUP(?) ; массив из 44 байтов
В арифметических операциях вычисления выполняются в области 16-битовых чисел, т.е. от результата всегда берутся только последние 16 разрядов (остаток от деления на 216).
Адресные выражения.Значениями адресных выражений являются 16-битовые адреса, поэтому все операции также выполняются по модулю 216. К простейшим адресным выражениям относятся:
метка (имя команды) и имя переменной, описанные по директиве DB, DW или DD (значениями таких выражений являются адреса меток и имен);
счетчик размещения.
Счетчик размещенияобозначается символ «$» и определяет адрес того предложения, в котором он встретился. При трансляции ассемблер следит за тем, в ячейку с каким адресом должен попасть машинный эквивалент очередного предложения программы. При ссылках на адрес можно указывать символ «$». Поэтому в разных предложениях счетчик размещения обозначает различные адреса.
Например, если адрес переменной А равен 100h, тогда:
A DW $ ; эквивалентно A DW 100h
В DW $ ; эквивалентно В DW 102h
Счетчик размещения удобен для вычисления размера памяти, занимаемой массивом, например:
X DW 10 DUP(?)
SIZE EQU $-X ; SIZE = 20
Здесь счетчик размещения определяет адрес первого байта за массивом, из которого вычитается начальный адрес массива.
Среди операторов, значением которых являются адреса, отметим операторы сложения и вычитания. Адресные выражения вида <имя>±<целое> используются для ссылок на безымянные ячейки памяти, как правило, элементы массивов. Например, в массиве:
A DB 0,1,2,3
именованным окажется только первый байт со значениями 0, а к остальным элементам массива нельзя будет обратиться по имени. Для доступа к таким ячейкам используются адресные выражения указанного вида. Например, сослаться на байт со значением 1 можно с помощью выражения А+1.
Операция вычитания адреса из числа, а также сложение, умножение и деление адресов не имеют смысла и запрещены. Однако допускается вычитание адресов. В этом случае результатом будет являться константа – смещение одного адреса относительного другого. Адреса запрещено указывать в явном (числовом) виде. Если указано число, то оно всегда воспринимается как константа, а не как адрес.
Опишите структуру команды на языке ассемблера.
Приведите примеры объявления числовых и символьных данных на языке ассемблера.
Перечислите допустимые операции над адресами.
Приведите примеры адресных выражений.
Для работы с оперативной памятью используются шина адреса и шина данных. Физически память устроена таким образом, что возможна адресация как 16-битовых слов, так и отдельных байтов памяти. Ширина шины адреса определяет максимальный объём физической памяти, непосредственно адресуемой процессором. Из рассмотрения формата машинной команды становится понятно, что большой объем оперативной памяти ведет к увеличению размера команд. Для их уменьшения поступают следующим образом.
Оперативную память разделяют на логические участки – сегменты. Причем начальные адреса сегментов могут быть любыми, но размер любого сегмента не должен превосходить 2mячеек (m < k, k – разрядность шина адреса). Тогдаабсолютный(физический)адреснекоторой ячейки памяти A можно представить в виде суммы:
![]()
где B – база сегмента, к которому относится ячейка A, disp – относительный адрес ячейки, отсчитанный от начала сегмента (адреса В) или смещение(displacement).
В результате большая часть адреса A будет приходиться на базу В. Если в команде требуется указать абсолютный адрес А, то большее слагаемое В сохраняется в регистре, а в команде указывается регистр и меньшее слагаемое disp. Записав в регистр адрес сегмента, далее, не меняя значение регистра, можно использовать его для доступа ко всем ячейкам данного сегмента.
Размер памяти в вычислительной системе на базе микропроцессора 8086 составляет 1 Мб, т.е. 220байтов (адреса 20-разрядные, k=20), а размер сегментов не должен превышать 64 Кб, т.е. 216байтов (смещения 16-разрядные адреса, m=16). Адреса принято записывать в шестнадцатеричной форме, поэтому физические адреса для 20-разрядной шины адреса находятся в пределах:
00000h [физический адрес]FFFFFh
Одновременно можно работать с четырьмя различными сегментами памяти: сегментом данных, кода, стека и дополнительным сегментом. На начало каждого из сегментов настраивается соответствующий регистр, и все адреса из данного сегмента по нему сегментируется. Взаимное расположение сегментов памяти может быть любым: они могут пересекаться, не пересекаться, либо полностью совпадать.