Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лабораторна робота16.doc
Скачиваний:
1
Добавлен:
23.11.2019
Размер:
105.47 Кб
Скачать

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

Параметри містяться в стек відразу перед викликом процедури. Саме цей метод використовують мови високого рівня, такі як С и 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], визначає число інших параметрів).

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

У цьому незвичайному методі передані процедурі дані розміщаються прямо в коді програми, відразу після команди CALL (як реалізована процедура print в одній зі стандартних бібліотек процедур для асемблера UCRLIB):

call print

db "This ASCIZ-line will be printed",0

(наступна команда)

Щоб прочитати параметр, процедура повинна використовувати його адресу, що автоматично передається в стеці як адреса повернення із процедури. Зрозуміло, функція повинна буде змінити адресу повернення на перший байт після кінця переданих параметрів перед виконанням команди 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

Передача параметрів у потоці коду, так само як і передача параметрів у стеці у зворотному порядку (справа наліво), дозволяє передавати різне число параметрів, але цей метод — єдиний, що дозволяє передати за значенням параметр різної довжини, що й продемонстрував цей приклад. Доступ до параметрів, переданим у потоці коду, трохи повільніше, ніж до параметрів, переданим у регістрах, глобальних змінних або стеці, і приблизно збігається з наступним методом.