Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
SP_MET_2.DOC
Скачиваний:
13
Добавлен:
02.05.2019
Размер:
689.66 Кб
Скачать

Передача параметров в потоке кода

В этом необычном методе передаваемые процедуре данные размещают­ся прямо в коде программы, сразу после команды CALL:

call print

db “This ASCIZ-line will be printer”

(следующая команда)

Чтобы прочитать параметр, процедура должна использовать его адрес, который автоматически передается в стеке как адрес возврата из проце­дуры. При этом функция перед выполнением команды RET должна будет изменить адрес возврата на первый байт после конца передаваемых параметров (с тем, чтобы было возможно продолжение работы программы после возврата из процедуры). Например, процедуру print можно реализовать следую­щим образом:

print proc near

push bp

mov bp, sp

push ax

push si

mov si, [bp+2] ; прочитать адрес возврата/начала данных

cld ; установить флаг направления для команды lodsb

print_readchar:

lodsb ; прочитать байт из строки,

test al, al ; если это 0 (конец строки),

jz print_done ; вывод строки закончен

int 29h ; вывести символ в AL на экран

jmp short print_readchar

print_done:

mov [bp+2], si ; поместить новый адрес возврата в стек

pop si

pop ax

pop bp

ret

print endp

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

Передача параметров в блоке параметров

Блок параметров — это участок памяти, содержащий параметры, так же как и в предыдущем примере, но располагающийся обычно в сегменте данных. Процедура получает адрес начала этого блока при помощи любого метода передачи параметров (в регистре, в переменной, в стеке, в коде или даже в другом блоке параметров). В качестве примеров ис­пользования этого метода можно назвать многие функции DOS и BIOS, например поиск файла, использующий блок параметров DTA, или загрузка (и исполнение) программы, использующая блок параметров ЕРВ.

      1. Локальные переменные

Часто процедурам требуются локальные переменные, которые не будут нужны после того, как процедура закончится. По аналогии с методами передачи параметров можно говорить о локальных переменных в регистрах — каждый регистр, который сохраняют при входе в процедуру и восстанавливают при выходе, фактически играет роль локальной пе­ременной. Единственный недостаток регистров в роли локальных пере­менных — их слишком мало. Следующий вариант — хранение локальных данных в переменной в сегменте данных — удобен и быстр для боль­шинства несложных ассемблерных программ, но процедуру, использу­ющую этот метод, нельзя вызывать рекурсивно: такая переменная на самом деле является глобальной и находится в одном и том же месте в памяти для каждого вызова процедуры. Третий и наиболее распрост­раненный способ хранения локальных переменных в процедуре — стек. Принято располагать локальные переменные в стеке сразу после сохра­ненного значения регистра ВР, так что на них можно ссылаться изнутри процедуры, как [ВР-2], [ВР-4], [ВР-6] и т.д.:

foobar proc near

foobar_x equ [bp+8] ; параметры

foobar_y equ [bp+6]

foobar_z equ [bp+4]

foobar_l equ [bp-2] ; локальные переменные

foobar_m equ [bp-4]

foobar_nl equ [bp-6]

push bp ; сохранить предыдущий ВР

mov bp, sp ; установить ВР для этой процедуры

sub sp, 6 ; зарезервировать 6 байт для

; локальных переменных

(тело процедуры)

mov sp,bp ; восстановить SP, выбросив

; из стека все локальные переменные

pop bp ; восстановить ВР вызвавшей процедуры

ret 6 ; вернуться, удалив параметры из стека

foobar endp

Внутри процедуры foobar стек будет заполнен следующим образом (см. рис. 5).

Последовательности команд, используемые в начале и в конце таких процедур, оказались настолько часто применяемыми, что в процессоре 80186 были введены специальные команды ENTER и LEAVE, выполня­ющие эти же самые действия:

foobar proc near

foobar_x equ [bp+8] ; параметры

foobar_y equ [bр+6]

foobar_z equ [bp+4]

foobar_l equ [bp-2] ; локальные переменные

foobar_m equ [bp-4]

foobar_n equ [bp-6]

enter 6, 0 ; push bp

; mov bp, sp

; sub sp, 6

(тело процедуры)

leave ; mov sp, bp

; pop bp

ret 6 ; вернуться, удалив параметры из стека

foobar endp

Х

Y

Z

IP

BP

BP

L

М

N

SP

Рис. 5. Стек при вызове процедуры foobar

Область в стеке, отводимая для локальных переменных вместе с активационной записью, называется стековым кадром.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]