Сист. прогр. Ч1 (1085770), страница 4
Текст из файла (страница 4)
Любые регистры общего назначения могут участвовать в операциях сложения и вычитания как 8-, так и 16-битовых значений.
Регистровые указатели: SP и ВР
Регистровые указатели SP и ВР обеспечивают системе доступ к данным в сегменте стека. Реже они используются для операций сложения и вычитания.
-
Регистр SP. Указатель стека обеспечивает использование стека
в памяти, позволяет временно хранить адреса и иногда
данные. Этот регистр связан с регистром SS для адресации
стека -
Регистр ВР. Указатель базы облегчает доступ к параметрам
(данным и адресам, переданным через стек).
Индексные регистры: SI и DI
Оба индексных регистра могут применяться для расширенной адресации и для использования в операциях сложения и вычитания.
-
Регистр SI. Этот регистр является индексом источника и
применяется для некоторых операций над строками. В
данном контексте регистр SI связан с регистром DS. -
Регистр DI. Этот регистр является индексом назначения и
применяется также для строковых операций. В данном
контексте регистр DI связан с регистром ES-
Рeгистр командного указателя: IP
Регистр IP содержит смещение на команду, которая должна быть выполнена. Обычно этот регистр в программе не применяется, но он может изменять свое значение при использовании отладчика DOS DEBUG при тестировании программы.
Флаговый регистр
Девять из 16 бит флагового регистра являются активными и определяют текущее состояние машины и результаты выполнения. Многие арифметические команды и команды сравнения изменяют состояние флагов. Назначение флаговых битов:
Флаг Назначение
О (Переполнение)
Указывает на переполнение старшего бита при арифметических командах.
D ( Направление)
Обозначает левое или правое направление пересылки или сравнения строковых данных (данных в памяти, превышающих длину одного слова).
I (Прерывание)
Указывает на возможность внешних прерываний.
Т (Пошаговый режим)
Обеспечивает возможность работы процессора в пошаговом режиме. Например, программа DOS DEBUG устанавливает данный флаг так, что возможно пошаговое выполнение каждой команды для проверки изменения содержимого регистров и памяти.
S (Знак)
Содержит результирующий знак после арифметических
операций (0 - плюс, 1 - минус).
Z (Ноль)
Показывает результат арифметических операций и операций сравнения (0 - ненулевой, 1 - нулевой результат).
А (Внешний перенос)
Содержит перенос из 3-го бита для 8-битовых данных, используется для специальных арифметических операций.
Р (Контроль четности)
Показывает четность младших 8-битовых данных (1 -четное и
0 - нечетное число).
С (Перенос)
Содержит перенос из старшего бита после арифметических операций, а также последний бит при сдвигах или циклических сдвигах.
При программировании на ассемблере наиболее часто используются флаги О, S, Z, и С для арифметических операций и операций сравнения, а флаг D для обозначения направления в операциях над строками.
ОБЩАЯ ПРОЦЕДУРА ПРОЕКТИРОВАНИЯ
Прежде чем детально обсуждать устройство ассемблера, рассмотрим общую проблему создания программного обеспечения. Ниже перечислены шесть этапов разработки:
1. Постановка задачи.
2. Определение структур данных.
3. Определение формата структур данных,
4. Выбор алгоритма.
5. Обеспечение модульности алгоритма, т. е. возможности разделить одну программу па независимые программные единицы.
6. Повторение шагов 1-5 для каждого модуля.
Подробнее рассмотрим составляющие компоненты системного программирования.
3. АССЕМБЛЕР
Двухпроходный ассемблер
В процессе трансляции исходной программы ассемблер делает два просмотра исходного текста. Одной из основных причин этого являются ссылки вперед. Это происходит в том случае, когда в некоторой команде кодируется метка, значение которой еще не определено ассемблером.
В первом проходе ассемблер просматривает всю исходную программу и строит таблицу идентификаторов, используемых в программе, т.е. имен полей данных и меток программы и их относительных адресов в программе. В первом проходе подсчитывается объем объектного кода, но сам объектный код не генерируется.
Во втором проходе ассемблер использует таблицу идентификаторов, построенную в первом проходе. Так как теперь уже известны длины и относительные адреса всех полей данных и команд, то ассемблер может сгенерировать объектный код для каждой команды. Ассемблер создает, если требуется, файлы: OBJ, LST и CRF.
Первый просмотр служит только для определения символов, во время второго просмотра генерируются команды и адреса. (Существуют однопросмотровые и многопросмотровые ассемблеры.) Конкретно ассемблер должен делать следующее:
1. Генерировать команды:
а) выделять мнемоническое обозначение в поле операции для того, чтобы выработать его машинный код;
б) определять остальные подполя — найти значение каждого символа, обработать литералы и присвоить адреса.
2. Обрабатывать псевдокоманды.
Можно сгруппировать эти задачи таким образом, чтобы они выполнялись в два последовательных прохода, или просмотра; с каждой задачей связываются один или несколько модулей ассемблера.
Первый просмотр. Цель — определить символы и литералы.
Для этого необходимо:
1. Определить длину машинных команд.
2. Следить за значениями счетчика адреса .
3. Запомнить значения символов для второго просмотра.
4. Обработать некоторые директивы (псевдокоманды), например EQU.
5. Запомнить литералы.
Второй просмотр. Цель — сгенерировать объектную программу. Для этого необходимо:
1. Найти значения символов.
2. Сгенерировать команды.
3. Сгенерировать данные.
4. Обработать псевдокоманды .
КОМПОНОВКА ПРОГРАММЫ
Если в результате ассемблирования не обнаружено ошибок, то следующий шаг - компоновка объектного модуля.
СТРУКТУРА АССЕМБЛЕРА.
Комментарии.
Комментарий может занимать всю строку или следовать за командой на той же строке, как показано в двух следующих примерах:
1. ;Эта строка полностью является комментарием
2. ADD АХ,ВХ ; Комментарий вместе с командой
Комментарии появляются только в листингах ассемблирования исходного модуля и не приводят к генерации машинных кодов, поэтому можно включать любое количество комментариев, не влияя на эффективность выполнения программы,
ФОРМАТ КОДИРОВАНИЯ
Основной формат кодирования команд Ассемблера имеет
следующий вид:
[метка] команда [операнд(ы)]
Метка (если имеется), команда и операнд (если имеется) разделяются по крайней мере одним пробелом или символом табуляции. Максимальная длина строки - 132 символа, однако большинство специалистов предпочитают работать со строками в 80 символов (соответственно ширине экрана). Примеры кодирования:
Метка Команда Операнд
COUNT DB 1 ;Имя, команда, один операнд
MOV АХ, 0 ;Команда, два операнда
Метки
Метка в языке Ассемблер может содержать следующие символы:
Буквы: от А до Z и от а до z
Цифры: от 0 до 9
Специальные символы: знак вопроса (?), точка (.) (только первый символ), знак "коммерческое эт" (@), подчеркивание (_), доллар ($).
Первым символом в метке должна быть буква или специальный символ. Ассемблер не делает различия между заглавными и строчными буквами. Максимальная длина метки - 31 символ. Примеры меток: COUNT, PAGE25, $Е10. Рекомендуется использовать описательные и смысловые метки. Все имена регистров, например, АХ, DI или AL, являются зарезервированными и используются только для указания соответствующих регистров. Например, в команде
ADD AX,BX
ассемблер автоматически знает, что АХ и ВХ относятся к регистрам. Однако, в команде
MOV REGSAVE,AX
ассемблер воспримет имя REGSAVE только в случае, если оно будет определено в сегменте данных.
Мнемоническая команда указывает ассемблеру, какое действие должен выполнить данный оператор, В сегменте данных команда определяет поле, рабочую область или константу. В сегменте кода команда определяет действие, например, пересылка (MOV) или сложение (ADD).
Операнд
Если команда специфицирует выполняемое действие, то операнд определяет: а) начальное значение данных или б) элементы, над которыми выполняется действие по команде. В следующем примере байт CNTR определен в сегменте данных и имеет нулевое значение:
Метка Команда Операнд
CNTR 0В 0 ; Определить байт с нулевым значением
Команда может иметь один или два операнда, или вообще быть без операндов. Рассмотрим следующие три примера:
Команда Операнд Комментарий
Нет операндов: RET ;Вернуться
Один операнд: INC СХ ;Увеличить СХ
Два операнда: ADD АХ,12 ;Прибавить 12 к АХ
Метка, команда и операнд не обязательно должны начинаться с какой-либо определенной позиции в строке. Однако, рекомендуется записывать их в колонку для большего удобства при чтении программы. Для этого, например, редактор DOS EDLIN обеспечивает табуляцию через каждые восемь позиций.
ДИРЕКТИВЫ
Ассемблер имеет ряд операторов, которые позволяют управлять процессом ассемблирования и формирования листинга. Эти операторы называются псевдокомандами или директивами. Они действуют только в процессе ассемблирования программы и не генерируют машинных кодов.
Директивы управления листингом: PAGE и TITLE
Ассемблер содержит ряд директив, управляющих форматом печати (или листинга). Обе директивы PAGE и TITLE можно использовать в любой программе.
Директива PAGE. В начале программы можно указать количество строк, распечатываемых на одной странице, и максимальное количество символов на одной строке. Для этой цели служит директива PAGE. Следующей директивой устанавливается формат 60 строк на страницу и 132 символа в строке:
PAGE 60,132
Количество строк на странице может быть в пределах от 10 до 255, а символов в строке - от 60 до 132. По умолчанию в ассемблере установлено PAGE 66,80.
Предположим, что счетчик строк установлен на 60. В этом случае ассемблер, распечатав 60 строк, выполняет прогон листа на начало следующей страницы и увеличивает номер страницы на единицу. Кроме того, можно заставить ассемблер сделать прогон листа на конкретной строке, например в конце сегмента. Для этого необходимо записать директиву PAGE без операндов. Ассемблер автоматически делает прогон листа при обработке директивы PAGE.
Директива TITLE. Для того, чтобы вверху каждой страницы листинга печатался заголовок (титул) программы, используется директива TITLE s следующем формате:
TITLE текст
В качестве текста рекомендуется использовать имя программы, под которым она находится в каталоге на диске. Например, если программа называется ASMSORT, то можно использовать это имя и описательный комментарий общей длиной до 60 символов:
TITLE ASMSORT - ассемблерная программа сортировки имен
В ассемблере также имеется директива подзаголовка SUBTTL, которая может оказаться полезной для очень больших программ, содержащих много подпрограмм.
Директива SEGMENT
Любые ассемблерные программы содержат по крайней мере один сегмент - сегмент кода. В некоторых программах используются сегмент для стековой памяти и сегмент данных для определения данных. Ассемблерная директива для описания сегмента SEGMENT имеет следующий формат:
Имя Директива имя SEGMENT
имя ENDS
Имя сегмента должно обязательно присутствовать, быть , уникальным и соответствовать соглашениям для имен в Ассемблере. Директива ENDS означает конец сегмента. Обе директивы SEGMENT и ENDS должны иметь одинаковые имена.
Директива SEGMENT может содержать три типа параметров: , выравнивание, объединение и класс.
1. Выравнивание, Данный параметр определяет границу начала сегмента. Обычным значением является PARA, по которому сегмент устанавливается на границу параграфа. В этом случае начальный адрес кратен 16, т.е. имеет шестнадцатеричный адрес nnn0. В случае отсутствия этого операнда ассемблер принимает по умолчанию PARA.
2. Объединение. Этот элемент определяет, объединяется ли данный сегмент с другими сегментами в процессе компоновки после ассемблирования (пояснения даны в следующем разделе "Компоновка программы"). Возможны следующие типы объединений: STACK, COMMON, PUBLIC, AT-выражение и MEMORY. Сегмент стека определяется следующим образом:
имя SEGMENT PARA STACK
Если отдельно ассемблированные программы должны объединяться компоновщиком, то можно использовать типы объединений: PUBLIC, COMMON и MEMORY. В случае, если программа не должна объединяться с другими программами, то указание этих типов должно быть опущено.