Процедура может размещаться в любом месте программы, но так, чтобы на нее случайным образом не попало управление.
Если процедуру просто вставить в общий поток команд, то микропроцессор будет воспринимать команды процедуры как часть этого потока и соответственно будет осуществлять выполнение команд процедуры.
Если имеется несколько процедур их обычно размещают рядом.
1. В начале сегмента кода
!!! Процедура должна быть расположена до первой выполняемой команды
Пример:
.code
name proc; ближняя по умолчанию
...
name endp
start:...
end start
2. В конце сегмента кода
!!! Процедура должна быть размещена после команды, возвращающей управление ОС
Пример
.code
start:...
mov ax,4C00h
int 21h
name proc near
..
name endp
end start
3. Можно разместить процедуру внутри сегмента кода
!!! Необходимо предусмотреть обход процедуры
Пример
.code
start:...
jmp metka
name proc
...
name endp
metka:...
end start
4. Процедура может быть описана в другом сегменте кода.
Вызов процедур
В принципе можно было бы обратиться к процедуре, просто переходом на метку - имя процедуры. Но!!! Необходимо сохранить где-то адрес возврата, т.е. адрес команды, следующей после процедуры.
|
|
В систему команд микропроцессора была введена специальная команда
Вызов процедуры, или переход с возвратом
CALL [модификатор] <имя процедуры>
Команда записывает адрес следующей за ней команды в стек, а затем осуществляет переход по метке <имя процедуры>.
Вспомним, что адрес следующей выполняемой команды задается парой CS:IP.
Если процедура описана как
· дальняя, то в стек по очереди заносятся два значения CS, IP.
· короткая - только значение IP
И при этом соответственно переход считается коротким или дальним.
Поэтому в с-ме команд имеется два варианта команды CALL.
!!! Ассемблер выберет правильный вариант, если процедура была описана до вызова. Если процедура будет описана позже транслятор считает процедуру ближней и формирует команду ближнего вызова. Если процедура окажется дальней, будет зафиксирована ошибка.
Для указания транслятору на то, что процедура, описанная ниже, будет дальней можно использовать <модификатор> со значением FAR PTR
Например, CALL FAR PTR NAME