Смекни!
smekni.com

ЯЗЫК МАКРОАССЕМБЛЕРА IBM PC (стр. 9 из 9)

Здесь описана универсальная схема организации работы подпрограмм.

В кокретных же случаях можно использовать более простые схемы. Напри­мер, параметры можно передавать не через стек, а через регистры, место под локальные величины можно отводить не в стеке, а в сегменте данных и т.п.

1.7.4 Процедуры в языке ассемблера

При составлении и вызове подпрограмм необходимо следить за тем, чтобы команды CALL и RET действовали согласовано - были одновременно близкими или дальними. В MASM эта проблема снимается, если подпрограм­му описать как процедуру. Процедуры имеют следующий вид:

имя_процедуры PROC [NEAR или FAR]

...

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

Хотя в директиве PROC после имени процедуры не ставится двоеточие, это имя относится к меткам и его можно указывать в командах перехода, в частности в команде CALL, когда надо вызвать процедуру. Это же имя должно быть повторено в директиве ENDP, заканчивающей описание проце­дуры. Предложения между этими двумя директивами образуют тело процеду­ры (подпрограмму). Имя процедуры является фактически меткой первой из команд тела, поэтому данную команду не надо специально метить.

Если в директиве PROC указан параметр NEAR или он вообще не ука­зан, то такая процедура считается "близкой" и обращаться к ней можно только из того сегмента команд, где она описана. Дело в том, что ас­семблер будет заменять все команды CALL, где указано имя данной проце­дуры, на машинные команды близкого перехода с возвратом, а все команды RET внутри процедуры - на близкие возвраты. Если же в директиве PROC указан параметр FAR, то это "дальняя" процедура: все обращения к ней и все команды RET внутри нее рассматриваются ассемблером как дальние пе­реходы. Обращаться к этой процедуре можно из любых сегментов команд. Таким образом, достаточно лишь указать тип процедуры (близкая она или дальняя), всю же остальную работу возьмет на себя ассемблер: переходы на нее и возвраты из нее будут автоматически согласованы с этим типом. В этом главное (и единственное) достоинство описания подпрограмм в ви­де процедур. (Отметим, что метки и имена, описанные в процедуре, не локализуются в ней.)

Например, вычисление ax:=sign(ax) можно описать в виде процедуры следующим образом:

sing proc far ;дальняя процедура

cmp ax,0

je sgn1 ;ax=0 - перейти к sgn1

mov ax,1 ;ax:=1 (флаги не изменились!)

jg sgn1 ;ax>0 - перейти к sgn1


mov ax,-1 ;ax:=-1

sgn1: ret ;дальний возврат

sign endp

...

Возможный пример обращения к этой процедуре:

;cx:=sign(var)

mov ax,var

call sign ;дальний вызов

mov cx,ax