Процедуры
Процедура - это часть кода, которая может быть вызвана из вашей
программы для выполнения какой-либо определенной задачи. Процедуры
делают программу более структурной и доступной для понимания. В общем
случае процедура возвращает программу к той же самой точке, откуда
она была вызвана.
Синтаксис для объявления процедуры:
имя PROC
; здесь находится
; код процедуры ...
RET
имя ENDP
имя - это имя процедуры. Одно и то же имя должно быть в верхней
и нижней части, это используется для проверки правильности закрытия
процедур.
Возможно, вы уже знаете, что команда
RET используется для
возвращения в операционную систему. Эта же команда используется для
возвращения из процедуры (фактически операционная система воспринимает
вашу программу, как специальную процедуру).
PROC и
ENDP - это директивы компилятора, поэтому они не
ассемблируются в какой-либо реальный машинный код. Компилятор только
запоминает адрес процедуры.
Команда
CALL используется для вызова процедуры.
Пример:
ORG 100h
CALL m1
MOV AX, 2
RET ; вернуться в операционную систему.
m1 PROC
MOV BX, 5
RET ; вернуться в программу, из которой была вызвана.
m1 ENDP
END
|
Вышеописанный пример вызывает процедуру
m1, которая выполняет
команду
MOV BX, 5. После окончания процедуры, программа
выполняет команду, следующую после команды
CALL, т.е. команду:
MOV AX, 2.
Есть несколько способов передачи параметров процедуре. Самый простой из них -
использование регистров. Здесь представлен пример процедуры, которая
принимает два параметра в регистрах
AL и
BL, умножает
их и возвращает результат в регистр
AX:
ORG 100h
MOV AL, 1
MOV BL, 2
CALL m2
CALL m2
CALL m2
CALL m2
RET ; вернуться в операционную систему.
m2 PROC
MUL BL ; AX = AL * BL.
RET ; вернуться в вызвавшую программу.
m2 ENDP
END
|
В этом примере значение регистра
AL изменяется каждый раз при
вызове процедуры, а состояние регистра
BL не изменяется. Таким
образом мы получили алгоритм вычисления числа
2 в
4-ой степени.
В результате в регистре
AX будет число
16 (или 10h).
Здесь дан другой пример, в котором используется процедура для вывода
на экран сообщения
Hello World!:
ORG 100h
LEA SI, msg ; загрузить адрес msg в регистр SI.
CALL print_me
RET ; вернуться в ОС.
; ==========================================================
; эта процедура печатает строку, строка должна оканчиваться
; нулем (иметь ноль в конце), адрес строки дожен быть в
; регистреhe SI:
print_me PROC
next_char:
CMP b.[SI], 0 ; проверить регистр SI, если он
JE stop ; равен 0, перейти к метке stop
MOV AL, [SI] ; иначе получить ASCII-символ.
MOV AH, 0Eh ; номер функции для печати символа.
INT 10h ; используем прерывание для печати
; символа из AL.
ADD SI, 1 ; увеличить индекс строкового массива
JMP next_char ; вернуться и напечатать другой символ
stop:
RET ; вернуться в программу.
print_me ENDP
; ==========================================================
msg DB 'Hello World!', 0 ; строка с нулевым окончанием
END
|
"
b." - префикс перед [SI] означает, что нам необходимо
сравнивать байты, а не слова. Если вы хотите сравнить слова, добавьте
префикс "
w." вместо "
b.". Если один из сравниваемых
операторов - регистр, то вставлять префиксы не требуется, так как
компилятор знает размер каждого регистра.
<<< Предыдущая часть <<<
>>> Следующая часть >>>