Л.И. Брусыяовскийу Ю.А. Михайлов
ОРГАНИЗАЦИЯ ВЗАИМОДЕЙСТВИЯ МЕЖЪЯЗЫКОВЫХ МОДУЛЕЙ (PASCAL-2 - F0RTRAN-4) В ОПЕРАЦИОННЫХ СИСТЕМАХ RSX-11M И RT-11
1, Введение
Средства вычислительной техники (СВТ) являются основной технической базой для создания любой комплексной системы автоматизации (КСА), характерным примером которой может служить комплексная система автоматизации компьютерной оптики (КСА КО) [l] . Развитое системное обеспечение большинства современных компьютеров позволяет выбрать операционные системы (ОС) в зависимости от места Используемых СВТ в КСА. При этом проблема мобильности программного обеспечения решается, как правило, за счет использования в различных ОС единого языка высокого уровня. Так, Для распространенного при решении задач КСА семейства 16-разрядных машин типа PDP-11 и совместимых с ними примерами таких языков могут служить FORTRAN-4 и PASCAL-2 [2-4].
Наличие компиляторов с PASCAL-2 в обеих ОС позволяет разрабатывать программы, эффективно использующие память машин: память под локальные объекты не включается в загрузочный модуль, а выделяется динамически по мере надобности в процессе работы, что крайне важно в силу ограниченности адресного пространства программ, работающих под управлением этих ОС, Однако достаточно большая часть существующего прикладного ПО в ОС RSX-11M и RT-11 написана на языке FORTRAN-4 (например, большое число различных библиотек научно-технических и инженерных расчетов). Поэтому вопрос об организации взаимодействия модулей, написанных на PASCAL-2 и FORTRAN-4, имеет важное практическое значение в рамках рассматриваемых
-ИЗ-
ОС. Такая необходимость может быть еще вызвана тем обстоятельством, что входящий в системы программирования PASCAL-2 обеих ОС пакет PASMAC, облегчающий интерфейс с ОС на ассемблере, не поддерживает автоматическую адресацию глобальных переменных, что может усложнить программирование и сопровождение разрабатываемых программ. В силу этого может оказаться целесообразным использовать входящий в состав обеих ОС интерфейс, оформленный в виде библиотеки системных подпрограмм, вызываемых с использованием обычной схемы FORTRAN (оператор CALL).
Хотя входной язык компилятора PASCAL-2 допускает обращение к внешним модулям, написанным на F0RTRAN-4, тем не менее существует ряд ограничений, препятствующих непосредственному использованию имеющегося в PASCAL-2 механизма вызова непаскальных модулей с описанием NONPASCAL.
Во-первых, оба компилятора генерируют код формирования среды для работы программ, написанных на соответствующих языках. В первую очередь это касается организации управляющих структур для организации ввода/вывода (в/в) и инициализации стека (через регистр R6). Из-за различия организации в/в все операции по в/в, использующие встроенные в язык программирования средства, должны выполняться в модулях, написанных на том же языке, что и главная программа. (Тем не менее в модуле, написанном на языке, отличном от языка главной программы, возможна организация в/в на физическом уровне посредством обращения к системным функциям ОС.)
Во-вторых, компиляторы используют различный механизм вызова внешних модулей: PASCAL-2 организует передачу параметров через стек (использование описателя у внешней процедуры/функции NONPASCAL заставляет компилятор генерировать при ее вызове последовательность кодов, аналогичную генерируемой компилятором F0RTRAN-4, то есть загружать в регистр R5 адрес списка адресов фактических аргументов). Однако даже при соблюдении стандартной последовательности вызова при организации взаимодействия модулей PASCAL-FORTRAN возможно возникновение проблем: передача имени внешнего модуля в качестве фактического параметра (непосредственно передать имя внешнего модуля, написанного на PASCAL-2, в модуль, написанный на языке FORTRAN, нельзя в силу особенностей генерации кода при передаче в качестве параметра имени внешней процедуры), доступ в фортрановском модуле к глобальным переменным PASCAL и т.д. и, наоборот, доступ к переменным блоков COMMON в модулях, написанных на PASCAL-2.
Непосредственный перенос двоичных файлов, содержащих записи переменной длины, превышающие 512 байт, из ОС RSX-11M в ОС RT-11 невозможен (системная утилита FLX ОС RSX-11M, предназначенная для переноса файлов между этими системами, обрабатывает записи длиной не более 512 байт). Ниже будет показано, как при помощи двух простых программ на PASCAL-2 легко решить эту проблему.
В данной статье будут рассмотрены практические приемы взаимодействия межъязыковых модулей (PASCAL-2 - F0RTRAN-4) в ОС RSX-11M и RT-11, а также организации работы с файлами переменной длины на PASCAL-2/RT-11 и методы переноса двоичных записей, длина которых превышает 512 байт, из ОС RSX-11M в ОС RT-11.
2. Организация взаимодействия PASCAL-FORTRAN
2.1. ПОЛУЧЕНИЕ АДРЕСА ЗАГРУЗКИ ВНЕШНЕГО МОДУЛЯ
При программировании на языке FORTRAN данная проблема легко решается с помощью вызова специальной функции, входящей в состав системы программирования FORTRAN-4 обеих ОС (например, для RT-11 это функция IADDR). Напомним, что для машин семейства PDP-11 адрес - это целое число в диапазоне 0 - 6 553 5. Получить адрес внешнего модуля в процедуре, написанной на языке PASCAL, можно, например, с помощью следующей вспомогательной раздельнокомпилируемой (для исключения проверки комплято-ром согласования типов фактического и формального параметров) функции:
\*Qnomaiп*> t vpe
ADDRESS : 0..65535;
•f une t i on ADDR ( I : ADDRESS )* ADDRESS; external; ■function ADDR; (* тело функции ADDR *) beg i n
ADDR:=J
end :
При вызове функции ADDR в качестве фактического параметра указывается имя внешнего модуля (описанного как EXTERNAL), адрес которого необходимо получить. Например, из программы на языке PASCAL в подпрограмму на языке FORTRAN (FORT) необходимо передать имя внешнего модуля ЕХТ в качестве фактического параметра. Схема вызова будет следующей:
type
ADDRESS s 0..65535; procedure EXT; external;
•function ADDR < procedure F > : ADDRESS; external; procedure FORK I s ADDRESS) ; nonpascal;
FORT(ADDR(EXT)>;
Отметим, что, независимо от того, на каком языке написан модуль ЕХТ, его необходимо описать как EXTERNAL, а не NONPASCAL. Не важно, имеет ли он формальные параметры, а также то, процедура (подпрограмма) это или
функция. Важно то, что в данном случае параметр (адрес точки загрузки внешнего модуля) должен передаваться в фортрановский модуль по значению.
Рассмотрим организацию модуля, написанного на PASCAL-2, вызываемого из модуля, написанного на F0RTRAN-4. При вызове внешнего модуля компилятор FORTRAN-4 заносит в регистр R5 адрес списка адресов фактических параметров. В младшем байте первого слова списка содержится число фактических параметров, а адреса фактических параметров начинаются со второго слова списка. Допустим, из модуля, написанного на языке FORTRAN, в модуль, написанный на PASCAL-2, передаются три параметра: целое число, вещественный массив и вещественное число. Для отмены генерации кода проверки согласования длины массива модуль, написанный на PASCAL-2, должен компилировать с ключом /NOCHECK. Имитация списка формальных параметров может иметь вид:
< *Зпот<л? п*- •
iirr.)cc?dur с? ЯХТ: ejr tier r«ai ;
Drncodur»* tXT;
l у pi4
VI CI HR т: агглv ! 1.-1И03 ot - i
< * i't iHf'Mi.- : ..i| .ЛМ^ТрОП
PARAMFTFR 1ЛЯТ - rc?cnr't
N,& ' r nttyq^r: * mhcjio •
AI : nl(?«F»r ; i* одрк ларэмртро *)
W ? • Vp.l7.T0R: (* ¿JflDGC -o *?
"ifv ; ГРЛ] r !* «/ipr«. < ! О Г^П^^М р'» *>
eriij:
V 3 r
(* aaptc i-i • '-'5
R5 origin 177705В : "PАРЛМЕ T c.K _ i. IЯ T j
beg l n
Ks Rrj-*4. й! 1: (* k - зиёчунию j-ro Фактического параметра *)
Если бы в данном случае схема вызовов была "PASCAL-FORTRAN-PASCAL" , то в приведенном выше модуле при необходимости можно было бы обращаться к глобальным переменным.
2.2. ДОСТУП К РАЗДЕЛЯЕМЫМ ПЕРЕМЕННЫМ
Теперь рассмотрим вопросы, связанные с доступом к глобальным переменным модулей, написанных на PASCAL-2, из модулей, написанных на FORTRAN-4.
Компилятор PASCAL-2 размещает глобальные переменные в программной секции с именем GLOBAL (или с именем соответствующего модуля при использовании ключа компиляции /OWN) со смещением в 4 байта относительно ее начала. Следовательно, для получения доступа к таким переменным в модуле, написанном на F0RTRAN-4, соответствующие переменные необходимо описать в блоке COMMON с именем GLOBAL (или соответствующим) со смещением в 4 байта относительно его начала:
-116-
var (> глобальные переменные *)
А - rea);
В : array ti..?00] oí boolean; С : record
АХ : intener;
ST : array С 3,.1003 ot char
end;
SUBROUTINE Fl( ПАРАМЕТРЫ, ЕСЛИ ЕСТЬ ) COMMON/GLOBAL/DUMMY,A,В,AX,ST REAL A
BYTE B<:?00) ,ST<100) INTEGER AX
Здесь DUMMY - фиктивная переменная, наличие которой обеспечивает смещение в 4 байта относительно начала блока COMMON с именем GLOBAL. Для доступа к переменным блока COMMON в модуле на PASCAL-2 аналогичный метод непригоден, поскольку исполнительная система PASCAL-2 использует первые 4 байта программной секции.PSECT, отводимой для размещения глобальных переменных, и, следовательно, помещенная в них информация будет потеряна. В этом случае метод доступа к переменным блока COMMON будет следующим: необходимо на языке FORTRAN-4 напасать подпрограмму, которая возвращала бы адреса (в виде 16-разрядных целых чисел) точек загрузки блоков COMMON (например, в RT-11 с помощью системной функции IADDR). В программе на PASCAL-2 этим адресам необходимо поставить в соответствие переменные ссылочного типа, базовый тип которых соответствует описанию блоков COMMON. Например, пусть необходимо получить доступ к переменным, размещенным в общих блоках COMI, COM2 и COM3, в процедуре, написанной на PASCÁL-2.
Тогда подпрограмма на FORTRAN-4 может иметь вид:
SUBROUTINE CADDR(ADDR) < INTEGER ADDR(l) COMMON/СОМ1/A(100),1(10) COMMON/COM?/В (200) , J (300) ,F COMMON /' COM3 / 2
ADDR(1)=IADDR(A) » или ADDR(1)=1ADDR(COMI)
ADDR(2)-IADDR(В> • или ADDR(2)=IADDR(COM2)
ADDR(3)~IADDR(7) ' или ADDR<3>=IADDR(COM3)
RETURN END
а вызывающая процедура на PASCAL-2:
type
COMADDR = array CI.. 33 o-f integer; CM1 = record
A : array CI.. 1003 o-f real; I : array CI.. 103 o-f integer; end; CM2 = record
B : array CI-.200*1 o+ real: I : array C i..3003 ot integer; end; CM3 = real; AC0M1 = 'SCM1; ACGM2 = •'CM2; AC0M3 = "*CM3;
var
C0M1 : AC0M1; COM2 : AC0M2; COM3 s AC0M3; ADDR s COMADDR; ..............
procedure CADDR( var A : COMADDR ); nonpascal;
begi n ..............
CADDR(ADDR);
COM1:=loophole(АСОМ1,ADDRC13); COM2: =1oophole(AC0M2,ADDR С 2 3); COM3:=1oopho1e(AC0M3,ADDR С 3 3);
К: =COM I . I С L 3 +C0M2'4. J С 1 3 :
3, Работа с файлами
3.1. ЗАПИСИ ПЕРЕМЕННОЙ ДЛИНЫ НА PASCAL
В PASCAL-2 все записи в нетекстовых файлах рассматриваются как записи фиксированной длины, определяемой типом файла. Работу с записями переменной длины на языке PASCAL можно организовать следующим образом, используя механизм раздельной компиляции модулей. Файл, содержащий записи переменной длины, необходимо описать как
type FBYTE = file of integer и весь в/в записей переменной длины организовать с помощью двух процедур/ написанных на PASCAL-2*. процедуры WVL (вывод) и RVL (ввод):
(*Qnomain*) type
FBVTE = -file o-f integer; ABYTE = arrav CI.. 103 o-f integer: procedure WVLCvar F:FBYTE; var X:ABYTE; K:integer); external; procedure WVL; var
I : integer; beg l n
write< F,К ); (* записать длину записи *)
(* запись структуры *)
■for I s = 1 to <K>l)div2 do write(F,XCI 3>
end;
procedure RVL(var F:FBYTE; var X:ABYTE; Ksinteger); external;
procedure RVL;
var
I : integer; beg i n
read( F,K ); (* читать длину записи *)
(* читать запись *)
■for I: = 1 to (K+l) di v2 do read (F, X С I 3 >
end;
Пример вызова процедуры WVL для записи:
type
FBYTE = -file o-f integer;
VREC1 = record ... end; VREC2 = record ___ end;
var Fl, F2 : FBYTE; X : VREC1; Y : VREC2; I : integer;
procedure WVL(var F:FBYTE; I,LENs i nteger);external ;
procedure RVL(var F:FBYTE; I:integer; var LEN:integer)
begi n
WVL (Fl , loophole (integer ,re-f (X) ) ,size (VREC1) ) ;
RVL(F2,loophole(integer ,re-f (Y) ) , I) ) ;
end -
Получающаяся структура записей будет идентична структуре записей переменной длины в ОС НБХ-ИМ.
3.2. ОБРАБОТКА СИМВОЛЬНЫХ СТРОК ПЕРЕМЕННОЙ ДЛИНЫ
Жесткий контроль типов, присущий языку программирования PASCAL-2, создает определенные проблемы, связанные с обработкой текста. Входящий в систему программирования PASCAL-2 пакет для работы со строками, не
обладает гибкостью, поскольку все строки в этом случае должны иметь одинаковую максимальную длину, независимо от конкретных случаев. Используя системную объектную библиотеку БУБЫВ, содержащую подпрограммы работы со строками, и механизм задания строк переменной длины (конец строки определяется первым вхождением нулевого байта), эту проблему можно легко решить, в качестве фактических параметров системных подпрограмм необходимо указывать не сами строки, а их адреса (в виде целых чисел): при этом эти адреса должны передаваться по значению. В качестве примера приведен вызов функции определения длины строки:
var S: packed arrayil-.SlD o-f char; ■function I. EN ( Is integer): integers nonpascal ; Ks~LEN( loophole (integer , re-f (S) ) > ;
3.3. ПЕРЕНОС ЗАПИСЕЙ ПЕРЕМЕННОЙ ДЛИНЫ ИЗ ОС RSX-11M В ОС RT-11 ПРИ ДЛИНЕ ЗАПИСЕЙ БОЛЬШЕ 512 БАЙТ
Данная проблема возникает при попытке переноса файлов, созданных операторами бесформатного ввода FORTRAN ОС RSX-11M, в ОС RT-11, когда длина записей переносимого Файла превышает 512 байт. При ее решении мы рекомендуем следующий алгоритм:
- программой PIP/RSX-11M сделать переносимый фа^л непрерывным (при помощи ключа /СО программы PIP);
- с помощью программы DMP/RSX-llM оаспечатать заголовок файла и определить адрес 1-го блока файла на диске (виртуальный блок 0).
Далее под управлением ОС RT-11 необходимо проделать следующее:
- командой
COPY/DEV/FIL DVl:/START:STARTADDRESS/END:ENDADDRESS DV2:FILNAM.EXT скопировать Файл с диска формата RSX-11 на диск формата RT-11, где ENDADDRESS - адрес 0-го блока файла на диске, полученный программой DMP + длина переносимого файла;
- если данный файл необходимо читать из модулей, написанных на PASCAL-2, то больше ничего делать не надо? этот файл уже можно читать приведенной выше процедурой RVL. Если данный файл необходимо обрабатывать операторами последовательного бесформатного ввода FORTRAN, необходимо выполнить две следующие программы (первая написанная на PASCAL-2 читает файл и формирует промежуточный выходной файл; вторая программа, написанная на FORTRAN-4, читает промежуточный файл и формирует бесформатные записи FORTRAN-4/RT-11).
с vpe
Fls tile o-f integer; F2: text; I,J,K: lnteger: Degi n
reset( Fl, ИМЯ ): rewrite' F2, ИМЯ ); while not eo-f(Fl) do Degin (* Длина записи *) read(Fl,I): wr i te v'F2, I) ; •for J: = 1 to (I +1) di v2 do begin read(Fl,k>: wri t.eln (F2,K)
end
end
end.
BYTE M<МАКСИМАЛЬНАЯ ДЛИНА В БАЙТАХ) INTEGER N(МАКСИМАЛЬНАЯ ДЛИНА В СЛОВАХ) EQUIVALENCE(М, N)
OPEN(UNIT-1, NAME='ИМЯПРОМЕЖФАЙЛА' ) , DISPOSE='DELETE') OPEN(UNIT=2, NAME-'ИМЯВЫХфАЙЛА'),FORM='UNFORMATTED')
1 READ <1,*,END=3 > L ! ДЛИНА В СЛОВАХ DO 2 1=1,(L+l)/2
2 READ(1,*) N(I) WRITE (2)(M(I),1=1,L) GOTO 1
3 STOP END
Обращение к монитору из программы, написанной на РА$СА1.-2
Для обращения к монитору непосредственно из программы, написанной на РА5САЬ-2, можно использовать встроенную (предопределенную) процедуру ЕМТ. Обращение в программе к этой процедуре эквивалентно выдаче команды ЕМТ с кодом, равным значению параметра процедуры ЕМТ. Например, вызов ЕМТ (375В) равносилен наличию инструкции:
ЕМТ 375
Заметим, что перед обращением к процедуре ЕМТ необходимо в регистр ИО загрузить адрес блока аргументов ЕМТ. Допустим, из программы на РА5САЬ-2 необходимо передать данные другому заданию с помощью системного вызова Формат таблицы аргументов ЕМТ имеет следующий вид:
к0 => *----------+--------
25 ! 0
1 Не использу».* «I я
! ВиР
+--------------------
! Wr.Nl
------------------
! «3
где
виг - адрес буфера для передачи данных; WCNT - длина буфера в словах.
Фрагмент программы на РА5САЬ-2 может иметь вид:
с onst BUFLEN=1000В;
type BUFFER=array C1..BUFLEN3 о+ integer; ARGBLOCK=record
CODE: packed array CI.-23 o-f 0..25S;
DUMMY: integer;
BUF: "BUFFER;
WCNT: integer;
ENDA: integer;
end;
var BUFF: BUFFER;
EMTARG: ARGBLOCK;
R0 origin 177700B : ЛARGBLOCK; <* это для ЭВМ типа PDP-11/40 *5
begi n
with EMTARG do begin CODEC 13:=0; CODEC 23:=25B; BUFF: =re-f (BUFF) ; UJCNT: =BUFLEN; ENDA:=0:
end;
R0: =re-f (EMTARG) ; EMT(375B);
Литература
1. Березный A. E., Брусилов с кий Jl.И. и др. Проект системы автоматизации проектирования, создания, исследования и применения элементов плоской оптики (версия 1). - В сб.: Компьютерная оптика, вып. 2. Автоматизация проектирования и технологии. М.: МЦНТИ, 1987.
2. PASCAL-2: Version 2.0 for RT-11. S.L., 1981.
3. PDP-11 PASCAL/RSX-11 Programmer's Guide. Maynard, Digital Equipment Corp., 19 83.
4. PDP-11 Fortran Language Reference Manual. Maynard, Digital Equipment Corp., 1979.