38. Определение подпрограмм, вызов подпрограммы и возврат из подпрограммы

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

Синтаксис процедуры следующий:

Имя_процедуры PROC [NEAR/FAR]
; тело процедуры
RET [n]
Имя_процедуры  ENDP

NEAR – может быть вызвана только из того сегмента кода, в котором объявлена. (Значение по умолчанию)
FAR – может быть вызвана из другого сегмента кода.

Где расположить код процедуры? Есть несколько вариантов:

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

Как вызвать процедуру?
Для этого используется команда CALL имя_процедуры — передает управление на первую команды процедуры, предварительно формируя точку возврата (контекст программы) – адрес команды следующей за CALL. Для ближней процедуры в стек помещается значение регистра ip, для дальней ip и cs.
В качестве адреса в CALL может быть:

  • имя процедуры
  • регистр, в котором находиться адрес ближней процедуры
  • поле памяти, для которого нужно явно указать, что в нем находиться адрес:
    call word ptr p1 – для ближней процедуры,
    call dword ptr p2 – для дальней процедуры

    .

Возврат из процедуры осуществляется при помощи команды RET [n]загружает в соответствующие регистры точку возврата (при выходе из ближней процедуры значение на вершине стека загружается в ip, при выходе из дальней – вершина загружается в ip, а следующие значение в cs).

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

Сохранение значения регистров можно осуществлять как в основной программе, так и в процедуре, это зависит от используемой модели памяти.

17.07.2015