Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Lektsia_12-14_2011_protsedury_SRC_slaydy.doc
Скачиваний:
9
Добавлен:
21.12.2018
Размер:
1 Mб
Скачать

3) Если имя – это имя константы, то тип должен быть abs.

Пример использования директив extrn и public на схеме связи двух модулей Модуль1 и Модуль2.

; -------------------------- Модуль 1 ------------------------

masm

model small

.stack 100h

.data

… …

.code

My_proc_1 proc

My_proc_1 endp

My_proc_2 proc

My_proc_2 endp

; -----Объявляем процедуру My_proc_1 видимой извне ----------

public My_proc_1

start:

….

….

end start

; -------------------------- Модуль 2 ------------------------

masm

model small

.stack 100h

.data

… …

.code

Extrn my_proc_1 ; объявляем процедуру my_proc_1 внешней

start:

….

….

call my_proc_1 ; вызов my_proc_1 из модуля 1

end star

Если необходимо собрать два модуля, например modul1.asm и modul2.asm в один исполняемый модуль, необходимо:

  1. Выполнить трансляцию модуля modul1.Asm и получить объектный модуль modul1.Obj;

  2. Выполнить трансляцию модуля modul2.Asm и получить объектный модуль modul2.Obj;

  3. Cкомпановать программу утилитой tlink командной строкой вида:

tlink /v modul1.obj+ modul2.obj

В итоге будет создан исполняемый модуль modul1.exe и можно будет исследовать данный модуль в отладчике, но при этом в турбо дебагере можно будет увидеть только текст программы modul1. Для того, чтобы войти в вызываемую процедуру, необходимо нажимать клавишу F7. Обработка этой команды приведёт к открытию второго окна, в котором будет выведен текст вызванной процедуры.

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

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

Параметры можно передавать с помощью одного из следующих механизмов:

по значению;

по ссылке;

.

Параметры можно передавать в одном из следующих мест:

в регистрах;

в глобальных переменных;

в стеке;

Передача параметров по значению

Процедуре передается собственно значение параметра. При этом фактически значение параметра копируется, и процедура использует его копию, так что модификация исходного параметра оказывается невозможной. Этот механизм применяется для передачи небольших параметров, таких как байты или слова.

Например, если параметры передаются в регистрах:

mov ax,word ptr value ; сделать копию значения

call procedure ; вызвать процедуру

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

Процедуре передается не значение переменной, а ее адрес, по которому процедура должна сама прочитать значение параметра. Этот механизм удобен для передачи больших массивов данных и для тех случаев, когда процедура должна модифицировать параметры, хотя он и медленнее из-за того, что процедура будет выполнять дополнительные действия для получения значений параметров.

mov ax,offset value

call procedure

Передача параметров в регистрах

Если процедура получает небольшое число параметров, то лучше всего их передавать через регистры. Примерами использования этого метода могут служить практически все вызовы прерываний DOS и BIOS. Языки высокого уровня обычно используют регистр АХ (ЕАХ) для того, чтобы возвращать результат работы функции.

Недостатки данного способа:

существуют ограничения на способ передачи аргументов через регистры;

имеется небольшое число доступных для пользователя регистров;

необходимо постоянно помнить о том, какая информация в каком регистре находится;

имеется ограничение размера передаваемых данных размерами регистра. Если размер данных превышает 16 или 32 бита, то передачу данных посредством регистров произвести нельзя. В этом случае передавать нужно не сами данные, а указатели на них.

Передача параметров в глобальных переменных

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

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

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

Текущее значение вершины стека хранится в регистре ESP. При записи в стек значение этого регистра уменьшается, то есть стек растет вниз от максимально возможного адреса (рис. 4).

Рис. 4. Стек.

При вызове подпрограммы параметры в большинстве случаев помещают в стек, а в EBP записывают текущее значение ESP. Тогда, если подпрограмма использует стек для хранения локальных переменных, ESP изменится, но EBP можно будет использовать для того, чтобы считывать значения параметров напрямую из стека (их смещения будут записываться как EBP+номер параметра).

Перед использованием стека для доступа к данным его содержимое необходимо правильно инициализировать, что предполагает формирование в нём адреса, который бы указывал на непосредственно переданные данные. Для этого в начало процедуры необходимо включить дополнительный фрагмент кода, который называется - пролог.

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

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

push X

push Y

push Z

call xyzzy

[...] ; x = 2 байта FF

xyzzy proc near ; y = 2 байта FD

; z = 2 байта FB

; ip =2 байта F9 < IP

; SP=F7 BP<SP; BP=F7

Пролог

push bp ;

mov bp,sp ;

;

xyzzy_x equ [bp+8]

xyzzy_y equ [bp+6]

xyzzy_z equ [bp+4]

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

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

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

Эпилог

mov sp,bp

pop bp

ret 6

xyzzy endp

Удалять параметры из стека можно:

  1. в процедуре;

  2. в вызывающей процедуру программе;

Если за освобождение стека от параметров отвечает вызывающая программа, то становится возможным вызвать несколько процедур с одними и теми же параметрами просто последовательными командами CALL.

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

Очистку стека от ненужных аргументов можно выполнить несколькими способами:

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