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

Параметры помещаются в стек сразу перед вызовом процедуры. Именно этот метод используют языки высокого уровня, такие как С и Pascal. Для чтения параметров из стека обычно используют не команду POP, а регистр ВР, в который помещают адрес вершины стека после входа в процедуру:

push parameter1 ; поместить параметр в стек

push parameter2

call procedure

add sp,4 ; освободить стек от параметров

[...]

procedure proc near

push bp

mov bp,sp

(команды, которые могут использовать стек)

mov ax,[bp+4] ; считать параметр 2.

; Его адрес в сегменте стека ВР + 4, потому что при выполнении

; команды CALL в стек поместили адрес возврата - 2 байта для процедуры

; типа NEAR (или 4 - для FAR), а потом еще и ВР - 2 байта

mov bx,[bp+6] ; считать параметр 1

(остальные команды)

рор bp

ret

procedure endp

Параметры в стеке, адрес возврата и старое значение ВР вместе называются активационной записью функции.

Для удобства ссылок на параметры, переданные в стеке, внутри функции иногда используют директивы EQU, чтобы не писать каждый раз точное смещение параметра от начала активационной записи (то есть от ВР), например так:

push X

push Y

push Z

call xyzzy

[...]

xyzzy proc near

xyzzy_z equ [bp+8]

xyzzy_y equ [bp+6]

xyzzy_x equ [bp+4]

push bp

mov bp,sp

(команды, которые могут использовать стек)

mov ax,xyzzy_x ;считать параметр X

(остальные команды)

pop bp

ret 6

xyzzy endp

При внимательном анализе этого метода передачи параметров возникает сразу два вопроса: кто должен удалять параметры из стека, процедура или вызывающая ее программа, и в каком порядке помещать параметры в стек. В обоих случаях оказывается, что оба варианта имеют свои «за» и «против», так, например, если стек освобождает процедура (командой RET число_байтов), то код программы получается меньшим, а если за освобождение стека от параметров отвечает вызывающая функция, как в нашем примере, то становится возможным вызвать несколько функций с одними и теми же параметрами просто последовательными командами CALL. Первый способ, более строгий, используется при реализации процедур в языке Pascal, а второй, дающий больше возможностей для оптимизации, - в языке С. Разумеется, если передача параметров через стек применяется и для возврата результатов работы процедуры, из стека не надо удалять все параметры, но популярные языки высокого уровня не пользуются этим методом. Кроме того, в языке С параметры помещают в стек в обратном порядке (справа налево), так что становятся возможными функции с изменяемым числом параметров (как, например, printf - первый параметр, считываемый из [ВР+4], определяет число остальных параметров). Но подробнее о тонкостях передачи параметров в стеке рассказано далее, а здесь приведен обзор методов.

Наши рекомендации