Подпрограмма объявляется точно также как и переменная, поэтому любое обращение к подпрограмме должно осуществляться внутри области действия объявления подпрограммы. Кроме того, обращение к подпрограмме не может встречаться внутри самой подпрограммы, т.е. до оператора END объявления этой подпрограммы.
Объявление подпрограммы состоит из 3-х частей: зарезервированного слова PROCEDURE, последовательности операторов, составляющих тело подпрограммы, и зарезервированного слова END:
<имя>:procedure [(<список параметров>)] [<адресное пространство>] [<атрибуты>]; <operator-1>; <operator-2>; ... <operator-N>; end [<имя>];
Например:
ProverkaDveri: Procedure; if VneshnDverZaperta and VnutrDverZaperta then Call VkluchitPitanie; else Call Trevoga; end ProverkaDveri;
где VkluchitPitanie и Trevoga это подпрограммы а VneshnDverZaperta и VnutrDverZaperta глобальные битовые переменные, объявленные раньше описываемой подпрограммы.
Имя подпрограммы в операторе PROCEDURE выглядит точно также, как и определение метки, однако имя подпрограммы не является меткой. Область действия подпрограммы определяется местоположением ее объявления в тексте программы точно так же, как область действия переменной определяется местоположением оператора DECLARE. Объявление подпрограммы может содержать в себе операторы объявления локальных переменных DECLARE, и эти операторы должны предшествовать первому выполняемому оператору в теле подпрограммы.
Как и в блоке DO, идентификатор, следующий за словом END, не оказывает никакого действия на программу, а только повышает наглядность программы и облегчает ее отладку. Если оператор END содержит идентификатор, то он обязательно должен быть тем же самым, что и идентификатор имени подпрограммы.
Параметры подпрограмм
Формальные параметры подпрограммы должны быть небазированными переменными, объявленными внутри подпрограммы. Их идентификаторы задаются в списке параметров в операторе PROCEDURE. Идентификаторы в списке разделяются запятыми, а сам список заключается в скобки. В списке параметров не допускаются применение массивов и структур. Если в подпрограмме нет формальных параметров, то список формальных параметров (включая скобки) в операторе PROCEDURE опускается. Каждый формальный параметр обязательно должен быть объявлен в теле подпрограммы оператором DECLARE, предшествующем первому исполняемому оператору.
При вызове подпрограммы с формальными параметрами в операторе CALL или обращении к функции должны содержаться фактические параметры. Каждый фактический параметр является выражением, значение которого присваивается соответствующему формальному параметру подпрограммы до того, как подпрограмма начнет выполняться. Например, следующая подпрограмма-процедура имеет 4 параметра, называемые Ukazat, N, Min, Max.
ProvDiapaz: Procedure(Ukazat, N, Min, Max); Declare Ukazat word; Declare (N, Min, Max, Perem Based Ukazat(1), I) byte; do I = 1 to N; if (Perem(I) < Min) or (Perem(I) > Max) then Call UstOshib; /*UstOshib это заранее объявленная подпрограмма */ end; end ProvDiapaz; ... Call ProvDiapaz(.Value, 20, low, up);
Эта подпрограмма просматривает N байтовых переменных. Через параметр Ukazat передается адрес первой из этих переменных. Если какая-нибудь из этих переменных меньше параметра Min или больше параметра Max, то вызывается объявленная ранее в этой же программе процедура UstOshib.
Переменные I и Perem не являются параметрами подпрограммы. Это обычные локальные переменные.
Отметим, что массив Perem объявлен с размерностью в один элемент. Так как это базированный массив, то важен только адрес переменной, задаваемый переменной Ukazat. Индекс в массиве может быть любым. При объявлении переменной можно указать в качестве размерности массива любое число большее 0. Размерность указывается для того, чтобы переменная Perem воспринималась как массив.
Вызов подпрограммы в конце примера передаёт приказ проверить находятся ли элементы массива Value(20) в диапазоне чисел от low до up. Адрес массива передан оператором .Value количество элементов массива числом 20. Использование базированной переменной, адрес которой передается в качестве параметра, позволяет процедуре иметь свой собственный неизменяемый идентификатор (Perem) для разных переменных, передаваемых при вызове процедуры.