Ассемблер с нуля. Часть 15. Процедуры (функции).

Процедуры в ассемблере

Процедуры в ассемблере.

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

Изучаем процедуры на примере goblin.com.

Пакет всего необходимого, включая исходники (DOS-1.rar) можно скачать с нашего сайта по ссылке.

Полный код нашей подопытной программы:

Goblin.com включает в себя несколько подпрограмм:

  • main proc
  • man proc
  • woman proc
  • goblin proc

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

Вызов процедуры в ассемблере.

Вызов процедуры в ассемблере осуществляется командой call (call — вызов). После вызова, процедура исполняет свой код и программа возвращается в точку возврата (выполняет дальнейший код, следующий за вызовом — командой call).

Процедура может иметь свои аргументы — данные, которые ей предоставляются для обработки и результат (входные и выходные данные — in/out).

Процедура в ассемблере обозначается названием и начинается оператором proc (procedure — процедура). Заканчивается процедур оператором end proc (end procedure — конец процедуры) и командой ret (return — возврат). В главной функции (main в нашем случае) команда ret после выхода в систему DOS не обязательна.

имя_процедуры proc

тело процедуры (код)

ret
endp

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

имя_процедуры proc

тело процедуры (код)

ret
имя_процедуры endp

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

Работа с процедурами на примере программы goblin.com.

Процедуры man proc, woman proc, goblin proc идентичны (на примере woman proc):

Вызов процедур goblin — прямой:

Вызов процедур woman и man косвенный (через указатель):

В организации работы процедуры задействованы команды CALL, RET, а также стек.

CALL (CALL).

Вызов процедуры с запоминанием в стеке точки возврата:

call адрес перехода.

Примеры для CALL:

RET (RETurn).

Возврат из процедуры обратно к месту вызова.

В действительности микропроцессор имеет три вида команды ret:

  • ret и retn — возврат из процедур ближнего типа
  • retf — возврат из процедур дальнего типа.

Выбор сделает транслятор, поэтому достаточно использовать ret.

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

Примеры для RET:

Необходимо отметить, что процедура может иметь параметры, через которые ей передаются данные, а также через которые она передаёт возвращаемые значения. Это может быть реализовано через регистры (аналогичный метод используют знакомые нам прерывания), а также через указатели на выделенные участки памяти (в нижеприведённом примере: mov dx,offset mes_womn; адрес выводимой строки).

Система передачи данных системных функций Windows, а также принятые способы реализации процедур современных операционок будут рассмотрены в цикле статей 32-битного и 64-битного программирования.

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

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *