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

Глава 3

пользуем старшую часть произведения и фактически ее может и не быть, сохранение и последующее восстановление регистра DX является обяза­тельным.

Передача параметров в подпрограмму через регистры общего назначе­ния или даже через сегментные регистры вполне возможна, однако на практике для передачи параметров чаще всего используют стек, хотя бы потому, что регистров немного, а в стек можно поместить любое число параметров. При этом применяется своеобразная методика работы со сте­ком не с помощью команд push и pop, а с помощью команд mov с кос­венной адресацией через регистр ВР, который архитектурно предназна­чен именно для адресации к стеку. Преобразуем пример 3-86 так, чтобы единственный в этом примере параметр (условная величина задержки) передавался в подпрограмму не через регистр SI, а через стек. Вызов под­программы delay в этом случае должен выполняться следующим образом:

push 2000 ;Проталкиваем в стек значение параметра

call delay ;Вызываем подпрограмму delay

Текст подпрограммы подвергнется значительным изменениям: ;Пример 3-8в. Передача параметра через стек

delay

ргос

push

CX

push

BP

mov

BP,SP

mov

CX,[BP+6]

dell:

push

CX

mov

cx,o

de!2:

loop

de!2

pop

CX

loop

dell

pop

BP

pop

CX

ret

2

;Процедура-подпрограмма

;Сохраним СХ основной программы

;Сохраним ВР

;Настроим ВР на текущую вершину стека

;Скопируем из стека параметр

;Сохраним его ;,*•

;Счетчик внутреннего цикла }':';-

;Внутренний цикл (64К шагов) ;#

;Восстановим внешний счетчик i\-:

; Внешний цикл

восстановим ВР

;и СХ программы ||,_

;Возврат и снятие со стека \

;ненужного уже параметра gj>;

Команда call, передавая управление подпрограмме, сохраняет в стеке адрес возврата в основную программу. Подпрограмма сохраняет в стеке еще два 16-разрядных регистра. В результате стек оказывается в состоянии, изображенном на рис. 3.9.

После сохранения в стеке исходного содержимого регистра ВР (в ос­новной программе нашего примера этот регистр не используется, однако в общем случае это может быть и не так), в регистр ВР копируется содер­жимое указателя стека, после чего в ВР оказывается смещение вершины стека. Далее командой mov в регистр СХ заносится содержимое ячейки стека, на 6 байтов ниже текущей вершины. В этом месте стека как раз находится передаваемый в подпрограмму параметр, как это показано в левом столбце рис. 3.9. Конкретную величину смещения относительно вер­шины стека надо для каждой подпрограммы определять индивидуально,

Команды и алгоритмы

139

ВР + 4

ВР + 6

SP

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

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

Параметр, полученный таким образом, используется далее в подпрог­рамме точно так же, как и в примере 3-8а.

Выполнив возложенную на нее задачу, подпрограмма восстанавлива­ет сохраненные ранее регистры и осуществляет возврат в основную про­грамму с помощью команды ret, в качестве аргумента которой указывает­ся число байтов, занимаемых в стеке отправленными туда перед вызовом подпрограммы параметрами. В нашем случае единственный параметр за­нимает 2 байт. Если здесь использовать обычную команду ret без аргумен­та, то после возврата в основную программу' параметр останется в стеке, и его надо будет оттуда извлекать (между прочим, не очень понятно, куда именно, ведь все регистры у нас могут быть заняты). Команда же с аргу­ментом, осуществив возврат в вызывающую программу, увеличивает со­держимое указателя стека на значение ее аргумента, тем самым осуществ­ляя логическое снятие параметра. Физически этот параметр, как, впро­чем, и все остальные данные, помещенные в стек, остается в стеке и будет затерт при дачьнейших обращениях к стеку.

Разумеется, в стек можно было поместить не один, а сколько угодно параметров. Тогда для их чтения надо было использовать несколько ко­манд mov со значениями смещения ВР+6, ВР+8, BP+OAh и т.д.

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