Цель работы
Целью данной работы является изучение написания процедур и макросов с использованием модульной структуры программы.
Процедуры на языке ассемблера
Для оформления процедур существуют специальные директивы proc/endp и машинная команда ret - возврат управления из процедуры вызывающей программе.
Формат команды ret: ret число.
Работа команды зависит от типа процедуры:
- для процедур ближнего типа - восстановить из стека содержимое eip/ip;
- для процедур дальнего типа - последовательно восстановить из стека содержимое eip/ip и сегментного регистра cs.
- если команда ret имеет операнд, то увеличить содержимое esp/sp на величину операнда число; при этом учитывается атрибут режима адресации - use16 или use32:
- если use16, то sp=sp+число), то есть указатель стека сдвигается на число байт, равное значению число;
- если use32, то sp=(sp+2*число), то есть указатель стека сдвигается на число слов, равное значению число.
Процедуры могут размещаться в программе:
- в начале программы (до первой исполняемой команды);
- в конце программы (после команды выхода в операционную систему);
- промежуточный вариант - тело процедуры располагается внутри другой процедуры или основной программы (с использованием команды безусловного перехода jmp);
- в другом модуле.
Вызов близкой или дальней процедуры с запоминанием в стеке адреса точки возврата осуществляется командой call (формат: call метка). Выполнение команды не влияет на флаги.
При ближней адресации - в стек заносится содержимое указателя команд eip/ip и в этот же регистр загружается новое значение адреса, соответствующее метке;
При дальней адресации - в стек заносится содержимое указателя команд eip/ip и cs. Затем в эти же регистры загружаются новые значения адресов, соответствующие дальней метке;
Передача аргументов через регистры
Существуют следующие варианты передачи аргументов в процедуру (модуль):
- Через регистры. Данные становятся доступными немедленно после передачи управления процедуре. Очень популярный способ при небольшом объеме передаваемых данных.
- Через общую область памяти. Необходимо использовать атрибут комбинирования сегментов - common (см. лаб. работу 1). Сегменты будут перекрываться в памяти и, следовательно, совместно использовать выделенную память.
- Через стек. Наиболее часто используемый способ. Суть его в том, что вызывающая процедура самостоятельно заносит в стек передаваемые данные, после чего производит вызов вызываемой процедуры.
- С помощью директив extrn и public. Директива extrn предназначена для объявления некоторого имени внешним по отношению к данному модулю. Это имя в другом модуле должно быть объявлено в директиве public. Директива public предназначена для объявления некоторого имени, определенного в этом модуле и видимого в других модулях.
Синтаксис директив:
Extrn имя:тип, …, имя:тип
Public имя, …, имя
Здесь имя - идентификатор, определенный в другом модуле. В качестве идентификатора могут выступать:
- имена переменных (определенных операторами db, dw и т.д.);
- имена процедур;
- имена констант (определенных операторами = и equ).
Возможные значения типа определяются допустимыми типами объектов для этих директив:
- если имя - это переменная, то тип может принимать значения byte, word, dword, pword, fword, qword и tbyte;
- если имя - это процедура, то тип может принимать значения near или far;
- если имя - это константа, то тип должен быть abs.
Остановимся более подробно при передаче параметров через стек. Приведем пример структуры вызываемой процедуры при ближней адресации.
Аsmpr proc near
;пролог
Push bp
Mov bp,sp
...
;доступ к элементам стека
mov ax, [bp+4];доступ к N-элементу
mov ax, [bp+6];доступ к N-1-элементу
mov ax, [bp+8];доступ к N-2-элементу
...
; эпилог
Mov sp,bp;восстановление sp
Pop bp;восстановление bp
Ret;возврат в вызывающую программу
asmpr endp;конец процедуры
На рис. 1. показана структура стека при ближней (а) и дальней (б) адресации в нутрии вызываемой процедуры.
Рис. 1. Структура стека в вызываемой процедуре при использовании различных видов адресации: а - ближняя адресация; б - дальняя адресация.
При использовании дальней адресации для доступа к элементам стека требуется поправка на +2.