
- •Лекции по предмету:
- •Системы счисления
- •Перевод целого числа
- •Перевод дробной части числа
- •Перевод числа из 8-ой и 16-ой сс в 2-ую сс
- •Арифметические операции в 2-ой сс
- •Представление чисел в эвм
- •Представление чисел с фиксированной точкой
- •Прямой код
- •Обратный код
- •Дополнительный код:
- •Правило сложения в дополнительном коде:
- •Представление чисел с плавающей точкой.
- •Понятие об архитектуре эвм
- •Структура эвм:
- •Устройство управления
- •Арифметико – логическое устройство (алу)
- •Классификация памяти. Операции с памятью.
- •Устройства ввода/вывода
- •Программная модель микропроцессора Intel 80/86
- •Адресация памяти
- •Адресация памяти в командах Ассемблера
- •Общий принцип косвенной адресации в процессоре 8086
- •Организация программы на языке ассемблер
Организация программы на языке ассемблер
При выполнении программы процессор одновременно использует несколько сегментов:
Сегмент кода (обязательный сегмент)
Сегмент данных
Сегмент стека
Дополнительные сегменты данных
Поэтому программа на языке ассемблера записывается как последовательность описания сегментов.
Никаких ограничений на взаимное расположение сегментов относительно друг друга нет.
Например они могут начинаться с одного и того же адреса и перекрывать друг друга, частично перекрывать друг друга, следовать друг за другом без пропусков или с пропусками.
Сегмент кода содержит исполняемую программу. Обычно первая исполняемая команда находится в начале этого сегмента и операционная система передаёт управление по адресу сегмента кода для запуска программы.
Адрес следующей команды определяется парой регистров CS: IP. Явным образом изменить эти регистры нельзя. Они изменяются командами передачи управления. Сегмент данных содержит переменные или константы, используемые в программе.
Переменные и константы описываются при помощи директив выделения памяти. По умолчанию для обращения к сегменту данных используется регистр DS. Однако можно назначить и использовать другой сегментный регистр.
Сегмент стека в основном предназначен для передачи параметров подпрограммам и системным прерываниям, а также сохранения адреса возврата. Адресация сегмента стека выполняется через пару регистров SS:SP. Стек организован по принципу : первый записан – последний считан, поэтому необходимо попарное использование команд записи в стек и чтение из стека. При записи в стек значение SP уменьшается, а при извлечении из стека увеличивается. Т.е. стек растёт от больших адресов к меньшим.
Директива описания сегмента в общем виде выглядит так:
Имя Segment <выравнивание> <Объединение> ‘Класс’
Имя ENDS
Выравнивание – способ выравнивания начала сегмента
Byte – без выравнивания
Word –выравнивание на границу слова, т.е. адрес начала сегмента должен быть кратен 2.
Para – выравнивание на границу параграфа. Адрес начала сегмента будет кратен 16.
Page – выравнивание на границу страницы. Адрес кратен 256.
Объединение – способ объединения сегментов с одним и тем же именем
None – сегменты не будут объединяться
Public – все сегменты с одинаковым именем объединяются и будут расположены друг за другом, т.е. будет организован один общий сегмент
Memory – соответствует Public, но после загрузки программы в регистр SP заносится адрес конца сегмента. Memory используется для сегмента стека.
Stack - синоним memory
Common – сегменты объединяются так, что они накладываются друг на друга с одного и того же базового адреса. Размер сегмента равен размеру наибольшего из объединяемых сегментов.
At адрес – размещает сегмент по указанному адресу.
Класс – используется компоновщиком для расположения сегментов в том или ином порядке.
Нельзя описывать сегменты с одинаковыми именами, но разными атрибутами.
Пример структуры программы будет выглядеть следующим образом:
STACKSG Segment Para Stack ‘STACK’ dw 80 dup(?) STACKSG ENDS
DATASG Segment Para Public ‘DATA’ -//- DATASG ENDS
CODESG Segment Para Public ‘Code’ assume DS : DATASG, SS : STACKSG, ES : NOTHING Begin: ……………………….. CODESG ENDS End Begin |
Директива assume устанавливает какой сегментный регистр используется для доступа к именам и веткам описанного раннее сегмента, но она не обеспечивает загрузки значения в эти сегментные регистры.
Последняя директива End Begin указывает метку к точке входа с которой должно начаться выполнение программы.
Загрузчик операционной системы устанавливает правильные адреса сегмента стека в сегментном регистре SS и сегмента кода в сегментном регистре CS. Сегментный регистр DS нужно инициализировать самостоятельно, поэтому модифицируем программу так:
STACKSG Segment Para Stack ‘STACK’ dw 80 dup(?) STACKSG ENDS
DATASG Segment Para Public ‘DATA’ -//- DATASG ENDS
CODESG Segment Para Public ‘Code’ assume DS : DATASG, SS : STACKSG, ES : NOTHING Begin: mov AX, DATASG mov DS, AX ……………………….. CODESG ENDS End Begin |
Чтобы завершить выполнение программы нужно вызвать функцию 21 прерывания:
QUIT: mov AL, 0 – код завершения
mov AH, 4СH – код функции прерывания 21h
int 21h – вызов 21 прерывания
CODESG ENDS
END Begin
Макрос exitcode делает тоже самое.