- •Команды языка ассемблера
- •3.2.1 Программные сегменты. Директива assume
- •6. Арифметические команды ……………………………………………….
- •Архитектура пк.
- •Регистры.
- •Регистры общего назначения.
- •1.1.2. Сегментные регистры
- •1.1.3 Регистр флагов
- •Организация памяти.
- •1.3. Представление данных
- •1.3.1 Типы данных
- •1.3.2 Представление символов и строк
- •Операторы программы на ассемблере
- •2.1 Команды языка ассемблера
- •2.2. Режимы адресации и форматы машинных команд
- •3. Псевдооператоры
- •3.1 Директивы определения данных
- •3.2 Структура программы на ассемблере
- •3.2.1 Программные сегменты. Директива assume
- •Начальная загрузка сегментных регистров
- •Упрощенная директива сегментации
- •4. Ассемблирование и компоновка программы.
- •5. Команды пересылки данных
- •5.1 Команды общего назначения
- •5.2 Команды работы со стеком
- •4.3 Команды ввода-вывода
- •5.4 Команды пересылки адреса
- •5.5 Команды пересылки флагов
- •6. Арифметические команды
- •Арифметические операции над целыми двоичными числами.
- •6.1.1 Сложение и вычитание.
- •6.1.2 Команды приращения и уменьшения приемника на единицу
- •6.2 Умножение и деление.
- •6.3 Изменение знака.
- •7. Логические операции
- •8. Сдвиги и циклические сдвиги
- •9. Строковые операции
- •10. Логика и организация программ
- •10.1 Безусловные переходы
- •10.2 Условные переходы
- •10.3 Циклы
- •10.4 Процедуры в языке ассемблера
- •10.5 Прерывания int
- •10.6 Системное программное обеспечение
- •10.6.1.1 Чтение клавиатуры.
- •10.6.1.2 Вывод символов на экран.
- •10.6.1.3 Завершение программ.
- •10.6.2.1 Выбор режимов дисплея.
- •11. Дисковая память
- •11.1 Оглавление диска (каталог)
- •11.2 Таблица распределения файлов
- •11.3 Операции ввода-вывода на диск
- •11.3.1 Запись файла на диск
- •11.3.1.1 Данные в формате asciiz
- •11.3.1.2 Файловый номер
- •11.3.1.3 Создание дискового файла
- •Чтение дискового файла
3.2 Структура программы на ассемблере
Рассмотрим, как правильно оформлять последовательность команд, чтобы транслятор мог их обработать, а микропроцессор выполнить.
3.2.1 Программные сегменты. Директива assume
Для того чтобы указать, что некоторая группа предложений программы на ассемблере образуют единый сегмент памяти, они оформляются как программный сегмент: перед ними ставится директива SEGMENT с операндами, после них - директива ENDS, причем в начале обеих этих директив должно быть указано одно и то же имя, играющее роль имени сегмента. Программа же в целом представляет собой последовательность таких программных сегментов, в конце которой указывается директива конца программы END, например:
DT1 SEGMENT PARA PUBLIC ‘DATA’ ; сегмент данных с именем DT1
A DB 0
B DW ?
DT1 ENDS
CODE SEGMENT ; кодовый сегмент CODE
ASSUME CS:CODE, DS:DT1
MAIN PROC
MOV AX,DT1 ;инициализация сегмента
MOV DS,AX ;данных
MOV AX,A
...
MOV AX,4C00H ; выход из
INT 21H ; программы
MAIN ENDP ; конец процедуры MAIN
CODE ENDS ; конец сегмента кода
END MAIN ;конец программы
Важно отметить, что функциональное назначение сегмента несколько шире, чем просто разбиение программ на блоки кода, данных и стека. Сегментация является частью более общего механизма, связанного с концепцией модульного программирования, она предполагает унификацию оформления объектных модулей, создаваемых компилятором, в том числе с разных языков программирования. Это позволяет объединять программы, написанные на разных языках. Именно для реализации различных вариантов такого объединения и предназначены операнды в директиве SEGMENT:
SEGMENT <тип выравнивания><тип комбинирования><класс><тип размера сегмента>
Первый операнд в директиве – атрибут выравнивания сегмента (тип выравнивания) сообщает компановщику о том, что нужно обеспечить размещение начала сегмента на заданной границе. Допустимые значения атрибута:
BYTE – выравнивание не выполняется. Сегмент может начинаться с любого адреса.
WORD – сегмент начинается по адресу, кратному двум.
DWORD – сегмент начинается по адресу кратному четырем.
PARA - сегмент начинается по адресу, кратному 16. Принимается по умолчанию.
PAGE -сегмент начинается по адресу кратному 256.
NEMPAGE – сегмент начинается по адресу, кратному 4 Кбайт.
Следующий атрибут комбинирования сегментов(комбинаторный тип) сообщает компоновщику, как нужно комбинировать сегменты различных модулей, имеющих одно и то же имя. По умолчанию атрибут комбинирования принимает значение PRIVATE. Атрибуты комбинирования могут быть следующими:
PRIVATE – сегмент не будет объединяться с другими сегментами с тем же именем вне данного модуля.
PUBLIC – компоновщик соединит все сегменты с одинаковыми именами.
COMMON – располагает все сегменты с одним и тем же именем по одному адресу.
AT xxxx – располагает сегмент по абсолютному адресу параграфа. Абсолютный адрес параграфа задается выражением xxxx.
STACK – определение сегмента стека. Заставляет компоновщик соединять все одноименные сегменты и вычислять адреса этих сегментов относительно регистра SS.
Атрибут класса сегмента (тип класса) – это заключенная в кавычки строка, помогающая компоновщику определить соответствующий порядок следования сегментов при объединении программ.
Все ссылки на предложения одного программного сегмента ассемблер сегментирует по умолчанию по одному и тому же сегментному регистру. По какому именно - устанавливается специальной директивой ASSUME. В нашем примере эта директива определяет, что все ссылки на сегмент CODE должны, если явно не указан сегментный регистр, сегментироваться по регистру CS, все ссылки на DT1 - по регистру DS, а все ссылки на DT2 - по регистру ES.
Встретив в тексте программы ссылку на какое-либо имя (например, на имя C в команде MOV AX,A), ассемблер определяет, в каком программном сегменте оно описано (у нас - в DT2). Затем по информации из директивы ASSUME узнает, какой сегментный регистр поставлен в соответствие этому сегменту (у нас - это ES), и далее образует адресную пару из данного регистра и смещения имени (у нас - ES:0), которую и записывает в формируемую машинную команду.
Таким образом, директива ASSUME избавляет программистов от необходимости выписывать полные адресные пары не только тогда, когда используются сегментные регистры по умолчанию, но тогда, когда в машинной команде нужно было бы явно указать сегментный регистр.
Директива ASSUME должна быть указана перед первой командой программы. В директиве ASSUME следует каждому сегменту ставить в соответствие сегментный регистр.