Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Финогенов-основы_языка_ассемблера.doc
Скачиваний:
46
Добавлен:
17.09.2019
Размер:
3.35 Mб
Скачать

Глава 2

Основы программирования

65

inc СН ;Плюс 1 к содержимому СН

push DS; ;DS сохраняется в стеке №

xchg ВХ.ВР ;ВХ и ВР обмениваются содержимым У

mov ES,AX ;Содержимое АХ пересылается в ES ||

Непосредственная адресация. Операнд (байт или слово) указывается в команде и после трансляции поступает в код команды; он может иметь любой смысл (число, адрес, код ASCII), а также быть представлен в виде символического обозначения.

mov AH,40h ;Число 40h загружается в АН

mov AL,'*" ;Код ASCII символа "*" загружается в AL

hit 21h ;Команда прерывания с аргументом 2Ш

limit = 528 ;Число 528 получает обозначение limit

mov CX,limit ;Число, обозначенное limit, загружается в СХ

Команда mov, использованная в последнем предложении, имеет два операнда; первый операнд определяется с помощью регистровой адреса­ции, второй — с помощью непосредственной.

Важным применением непосредственной адресации является пере­сылка относительных адресов (смещений). Чтобы указать, что речь идет об относительном адресе данной ячейки, а не об ее содержимом, исполь­зуется описатель onset (смещение):

;Сегмент данных mes db "Урок Г' ;Сегмент команд mov DX.oflset mes

;Строка символов

;Адрес строки засылается в DX

В приведенном примере относительный адрес строки mes, т.е. рассто­яние в байтах первого байта этой строки от начала сегмента, в котором она находится, заносится в регистр DX.

Прямая адресация памяти. Адресуется память; адрес ячейки памяти (слова или байта) указывается в команде (обычно в символической фор­ме) и поступает в код команды:

;Сегмент данных me ml dw О тет2 db 230 ;Сегменг команд

inc meml

mov

mov

;Слово памяти содержит О ;Байт памяти содержит 230

;Содержимое слова meml увеличивается на 1 DX,meml ;Содержимое слова с именем meml загружается в DX AL,mem2 ;Содержимое байта с именем mem2 загружается в AL

Сравнивая этот пример с предыдущим, мы видим, что указание в команде имени ячейки памяти обозначает, что операндом является со-

держимое этой ячейки; указание имени ячейки с описателем onset — что операндом является адрес ячейки.

Прямая адресация памяти на первой взгляд кажется простой и на­глядной. Если мы хотим обратиться, например, к ячейке meml, мы про­сто указываем ее имя в программе. В действительности, однако, дело об­стоит сложнее. Вспомним, что адрес любой ячейки состоит из двух ком­понентов: сегментного адреса и смещения. Обозначения meml и mem2 в предыдущем примере, очевидно, являются смещениями. Сегментные же адреса хранятся в сегментных регистрах. Однако сегментных регистров че­тыре: DS, ES, CS и SS, Каким образом процессор узнает, из какого реги­стра взять сегментный адрес, и как сообщить ему об этом в программе'

Процессор различает группу кодов, носящих название префиксов. Имеется несколько групп префиксов: повторения, размера адреса, разме­ра операнда, замены сегмента. Здесь нас будут интересовать префиксы замены сегмента.

Команды процессора, обращающиеся к памяти, могут в качестве пер­вого байта своего кода содержать префикс замены сегмента, с помощью которого процессор определяет, из какого сегментного регистра взять сег­ментный адрес. Для сегментного регистра ES код префикса составляет 26h, для SS — 36U, для CS — 2Eh. Если префикс отсутствует, сегментный адрес берется из регистра DS (хотя для него тоже предусмотрен свой префикс).

Если в начале программы с помощью директивы assume указано со­ответствие сегменту данных сегментного регистра DS

assume DS:data

то команды обращения к памяти транслируются без какого-либо префик­са, а процессор при выполнении этих команд берет сегментный адрес из регистра DS.

Если в директиве assume указано соответствие сегмента данных регистру ES assume ES:data

(в этом случае сегмент данных должен располагаться перед сегментом команд), то команды обращения к полям этого сегмента транслируются с добавлением префикса замены для сегмента ES. При этом предложения программы выглядят обычным образом; в них по-прежнему просто ука­зываются имена полей данных, к которым производится обращение.

Однако в ряде случаев префикс замены сегмента должен указываться в программе в явной форме. Такая ситуация возникает, например, если Данные расположены в сегменте команд, что типично для резидентных обработчиков прерываний. Для обращения к таким данным можно, ко­нечно, использовать регистр DS, если предварительно настроить его на сегмент команд, но проще выполнить адресацию через регистр CS, кото­рый и так уже настроен должным образом. Если в сегменте команд содер­жится поле данных с именем mem, то команда чтения из этого поля будет выглядеть следующим образом: