Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Assembler.doc
Скачиваний:
10
Добавлен:
20.04.2019
Размер:
12.47 Mб
Скачать

Подпрограммы

Подпрограмма часть программы, которая выполняет некоторую четко определенную операцию над данными, определяемыми параметрами.

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

После выполнения подпрограммы, управление передается в ту точку программы, из которой был осуществлен вызов.

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

Главное отличие этих команд от команд перехода – возможность запомнить точку программы, из которой был сделан вызов подпрограммы и вернуться в эту точку.

Для сохранения информации о точке возврата используется стек. Это позволяет выполнять вложенные и рекурсивные вызовы подпрограмм.

Команда CALL – вызов подпрограммы

Формат команды

call Метка

Действие команды

push EIP ; запомнить точку возврата

jmp Метка ; перейти к подпрограмме

Команда RET – возврат из подпрограммы

Формат команды

ret

Действие команды

pop EIP ; вернуться в исходную точку

Порядок исполнения команд при вызове подпрограмм

основная программа:

. . .

. . .

call Подпрограмма

. . .

. . .

. . .

. . .

Подпрограмма:

. . .

. . .

ret

Подпрограммы могут располагаться в любом месте сегмента кода.

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

Поэтому необходимо обязательно предусмотреть «обход» подпрограммы, например, с помощью команды JMP.

Чтобы избежать возможных ошибок, подпрограммы следует располагать:

в начале программы (до первой исполняемой команды);

в конце программы (после команды, возвращающей управление операционной системе);

в другом модуле.

Способы передачи параметров в подпрограмму

Существует несколько способов передачи параметров в подпрограмму:

через регистры общего назначения;

через общую память;

через стек.

Эти же способы используются при возврате результатов работы подпрограммы.

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

Перед вызовом подпрограммы значения параметров заносятся в регистры общего назначения.

Пример. Вычисление среднего двух чисел: C=(A+B)/2

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

Достоинства метода: – просто; – быстро

Недостатки метода: – трудности с использованием регистров в подпрограмме (они заняты параметрами); – ограниченное количество параметров; – трудности с реализацией вложенных вызовов и рекурсии

Передача параметров подпрограммы через память

Перед вызовом подпрограммы значения параметров заносятся в ячейки памяти (например, массив).

Пример. Вычисление среднего двух чисел: C=(A+B)/2

Передача параметров подпрограммы через память

Достоинства метода: – неограниченное количество параметров, в том числе и переменное

Недостатки метода: – низкое быстродействие; – большие трудности с реализацией рекурсии или косвенной рекурсии

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

Перед вызовом подпрограммы значения параметров заносятся в стек.

Пример. Вычисление среднего двух чисел: C=(A+B)/2

push A

push B

push 0

call Srednee

pop C

add esp,8

Srednee:

mov eax,[esp+8]

add eax,[esp+12]

cdq

mov ebx,2

idiv ebx

mov [esp+4],eax

ret

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

Достоинства метода: – простота передачи параметров; – неограниченное количество параметров, в том числе и переменное; – легко организовываются вложенные и рекурсивные вызовы функций

Недостатки метода: – требуется внимательно следить за размещением параметров в стеке, особенно, когда он используется внутри подпрограммы; – требуется выравнивать стек после возврата из подпрограммы.

В языке программирования С используется комбинация двух способов передачи параметров:

в подпрограмму параметры передаются через стек, причем справа-налево (т.е. первым в стеке сохраняется последний параметр, а первый параметр сохраняется последним);

из подпрограммы результат возвращается в регистрах: 1 байт – в регистре AL; 2 байта – в регистре AX; 4 байта – в регистре EAX; 8 байт – в регистрах (EDX,EAX)

В функциях Windows API к этим соглашениям добавлено следующее:

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

Для этих целей используется расширенный вариант команды RET

Формат команды

ret число

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

Действие команды

pop EIP ; вернуться в исходную точку add ESP, число ; выровнять стек на «число» байт

Набор соглашений по вызову функций в Win32 API называется STDCALL

Пример. Вычисление среднего двух чисел с использованием соглашения STDCALL

push B

push A

call Srednee

mov C,eax

Srednee:

mov eax,[esp+8]

add eax,[esp+4]

cdq

mov ebx,2

idiv ebx

ret 8

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

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

В таких случаях используется регистр EBP – указатель кадра стека, значение которого остается неизменным. Следовательно, смещения параметров и переменных также фиксируются.

Типичный пролог в подпрограмме:

push ebp ; сохраняем исходное значение ebp

mov ebp,esp ; фиксируем текущий указатель

sub esp, размер ; делаем «окно» заданного размера

В результате получаем следующую конфигурацию стека:

Содержимое стека:

[EBP] – исходное значение EBP

[EBP+4] – адрес точки возврата

[EBP+8] – первый параметр

[EBP+12] – второй параметр

. . .

[EBP–4] – первая переменная

[EBP–8] – вторая переменная

. . .

Типичный эпилог в подпрограмме:

mov esp,ebp ; удаляем «окно» в стеке

pop ebp ; восстанавливаем исходное значение ebp

ret размер ; возврат + выравнивание стека

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