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

Глава 2

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

71

j mov byte ptr ES:[DI],'O* ;Символ на экран

mov byte ptr ES:2[DI],'K' ;3апишем символ в следующую позицию mov byte ptr ES:4[DI],T ;3апишем символ в следующую позицию

В этом примере в качестве базового выбран регистр DI; в него зано­сится базовый относительный адрес памяти, в данном случае смещение в видеобуфере к началу последней строки экрана. Модификация этого ад­реса с целью получить смещение по строке экрана осуществляется с по­мощью констант 2 и 4, которые при вычислении процессором исполни­тельного адреса прибавляются к содержимому базового регистра DI.

Иногда можно встретиться с альтернативными обозначениями того же способа адресации, которые допускает ассемблер. Вместо, например, 4[ВХ] можно с таким же успехом написать [ВХ+4], 4+[ВХ] или [ВХ]+4. Такая неоднозначность языка ничего, кроме путаницы, не приносит, однако ее надо иметь в виду, так как с этими обозначениями можно стол­кнуться, например, рассматривая текст деассемблированной программы.

Рассмотрим теперь пример использования базовой адресации со сме­щением при обращении к стеку:

;Основная программа

push DS ;В стек загружаются значения

push ES ;трех регистров,

push SI передаваемых подпрограмме

call mysub ;Вызов подпрограммы mysub,

;использующей эти параметры

;Подпрограмма mysub

mov ВР,5Р;Поместим в ВР текущий адрес вершины стека mov АХ,2[ВР] ;Читаем в АХ последний параметр (SI) mov ВХ,4[ВР] ;Читасм в ВХ предыдущий параметр (ES) mov СХ,6[ВР] ;Читаем в СХ первый параметр (DS)

Здесь продемонстрирован классический прием чтения содержимого стека без извлечения из него этого содержимого. После того, как основ­ная программа сохранила в стеке три параметра, которые потребуются подпрограмме, командой call вызывается подпрограмма mysub. Эта ко­манда сохраняет в стеке адрес возврата (адрес следующего за call предло­жения основной программы) и осуществляет переход на подпрограмму-Состояние стека при входе в подпрограмму приведено на рис. 2.15.

Если бы подпрограмма просто сняла со стека находящиеся там пара­метры, она первым делом изъяла бы из стека адрес возврата, и лишила бы себя возможности вернуться в основную программу (подробнее воп­росы вызова подпрограммы и возврата из нее будут обсуждаться в после­дующих разделах). Поэтому в данном случае вместо команд pop удобнее воспользоваться командами mov. Подпрограмма копирует в ВР содержи­мое SP и использует затем этот адрес в качестве базового, модифицируя его с помощью базовой адресации со смещением.

Состояние SP после перехода на подпрограмму

Параметры, загруженные в стек основной программой

Исходное состояние SP

Смещения в стеке относительно текущего состояния SP

0 2 4 б

.Адрес возврата

<

ч

<

SI

ES

DS

Рис. 2.15. Состояние стека после загрузки в него трех параметров и перехода на подпрограмму.

Кстати, мы опять сталкиваемся здесь с той весьма обычной ситуаци­ей, когда программист не имеет возможности обращаться по наглядным символическим адресам, которьк в стеке, естественно, нет, а вынужден определять «вручную» смещения к интересующим его элементам стека. При этом необходимо учесть и алгоритм выполнения команды call, кото­рая, сохраняя в стеке адрес возврата в основную программу, смещает указатель стека еще на одно слово.

В нашем фрагментарном примере мы не рассматриваем вопрос воз­врата в основную программу. Вдумчивый читатель мог также усомниться в правильности или, лучше сказать, в разумности текста подпрограммы. Ведь перенося параметры из стека в регистры общего назначения, подпрог­рамма затирает их исходное содержимое. Если же они не содержали ниче­го нужного, то ими можно было воспользоваться для передачи парамет­ров в подпрограмму, а не связываться с мало наглядными операциями со стеком. Действительно, ради краткости мы опустили операции, практи­чески необходимые в любой подпрограмме — сохранение в стеке (опять в стеке!) тех регистров, которые будут использоваться в подпрограмме. Кста­ти, это относится и к регистру ВР. В реальной подпрограмме эти действия следовало выполнить, что привело бы к изменению смещений при реги­стре ВХ, которые приняли бы значения (с учетом сохранения 4 регист­ров) 10, 12 и 14.

Во всех приведенных выше примерах регистр использовался для хране­ния базового адреса, а смещение, если оно требовалось, указывалось в виде Константы. Возможна и обратная ситуация, когда в качестве смещения выс­тупает адрес массива, а в регистре находится индекс адресуемого элемента в этом массиве. Рассмотрим относительно решгьный пример такого рода

Пусть нам надо заполнить массив из 10000 слов натуральным рядом Чисел. Зарезервируем в сегменте данных место под этот массив, а в сег-

72