Разработка мобильного мультипрограммного обеспечения на базе СП PASCAL-2
Автор: Брусиловский Л.И., Михайлов Ю.А.
Журнал: Компьютерная оптика @computer-optics
Рубрика: Автоматизация проектирования
Статья в выпуске: 8, 1990 года.
Бесплатный доступ
Рассматривается метод реализации в системе программирования (СП) Pascal-2 сопрограмм, аналогичных введенным в язык программирования Modula-2. Описывается возможность разработки мобильного мультипрограммного обеспечения на базе СП Pascal-2, расширенного средствами сопрограмм.
Короткий адрес: https://sciup.org/14058231
IDR: 14058231
Текст научной статьи Разработка мобильного мультипрограммного обеспечения на базе СП PASCAL-2
-
8 последнее время все большую популярность завоевывают языки высокого уровня, имеющие средства доступа к "нижнему уровню" и позволяющие создавать сложные пакеты программ, обладающих высокой степенью мобильности. В первую очередь это языки ADA [l]z С [2], Modula-2 [3] и диалекты языка Pascal [4]. Сравнение названных языков программирования со стороны разработки мобильного программного обеспечения (кроме Modula-2) приведено в [5].
Язык Modula-2 часто представляется как "Паскаль без недостатков". В то же время в различных реализациях языка Pascal предприняты попытки устранить ряд его "узких мест". В первую очередь это касается мобильной СП Pascal-2 [6,?], реализация которой имеется для таких операционных систем, как RT/11 /TSX-Plus/ SHAREplus, RSX-11M, 1AS, RSTS/E (линия ЭВМ PDP-11), VMS (линия ЭВМ VAX), MS-DOS/PC-DOS (линия ЭВМ IBM РС/ХТ/АТ), VersaDOS (линия ЭВМ на базе микропроцессоров фирмы Motorola) [6-8].
В СП Pascal-2 введены расширения стандартного языка Pascal, которые не только уравнивают его возможности с Modula-2, но в ряде случаев выгодно его отличают. Это, например:
-
- возможность передачи в качестве параметров многомерных массивов с переменными границами;
-
- константы с типом;
-
- работа с файлами прямого доступа;
-
- возможность обращения к модулям, написанным на других языках программирования .
-
2. Подпрограммы и сопрограммы
Кроме того, компилятор Pascal-2 является оптимизирующим, а в СП Pascal-2 имеются мощные средства интерактивной отладки программ на лексике языка высокого уровня и возможности профилирования выполнения программ. Поэтому СП Pascal-2 является реальным конкурентом СП Modula-2 в области создания больших мобильных пакетов программ |Э_11]•
Тем не менее в СП Pascal-2 нет средств, аналогичных механизму сопрограмм (процессов) в языке Modula-2, с помощью которых легко реализуются такие компоненты операционных систем, как, например, мониторы.
8 данной статье предлагаются средства реализации механизма сопрограмм в среде СП Pascal-2.
Основное различие между сопрограммами и подпрограммами заключается в том, что выполнение сопрограмм может быть приостановлено с сохранением контекста значений локальных переменных, пока процессор занят выполнением некоторой другой работы, а потом возобновлено с точки останова в старом контексте. При вызове подпрограммы ей передается управление на одну из точек входа. Контекст локальных переменных вызывающей подпрограммы сохраняется, а ее выполнение будет возобновлено со следующего за вызовом оператора после полного завершения работы вызванной подпрограммы, причем контекст вызванной сопрограммы не сохраняется. Повторное обращение к вызываемой подпрограмме вновь передаст управление на одну из точек входа в новом контексте.
Наглядно различие между со- и подпрограммами можно увидеть на примере совместной работы двух модулей, обращающихся друг к другу. В случае подпрограмм такие взаимные обращения приводят к бесконечной рекурсии (что, впрочем, может быть предусмотрено алгоритмом). В случае сопрограмм сохраняется последовательное выполнение. Схематически различие между со- и подпрограммами показано на рис. 1 и рис. 2.

Модуль С1 Модуль С2
Рис. 1. Бесконечная рекурсия при взаимном вызове двух подпрограмм

Модуль С 1
Модуль С2
Рис. 2. Передача управления между
сопрограммами
В языке Modula-2 работа с сопрограммами реализуется с помощью двух процедур, определенных в модуле SYSTEM (NewProcess и Transfer), и двух процедур и одной функции, определенных в модуле STORAGE (Allocate, Deallocate, Available). Кроме того, в модуле SYSTEM определяются типы данных Address и Process,
структура которых является системно-з а в и с имой .
Преобразование процедуры, не имеющей параметров, в сопрограмму (т.е. в Process) выполняется при вызове процедуры NewProcess, заголовок которой обычно имеет вид:
Procedure NewProcess (Р, STADDR, SIZE : Address; var PROC : Process): external;
3, Реализация сопрограмм в СП PASCAL-2
Наличие в СП Pascal-2 средств раздельной компиляции внешних процедур и функций, связи с ассемблером и ряда средств нижнего уровня позволяет реализовать на Pascal-2 механизм сопрограмм, а возможность включения модулей исходного текста на этапе компиляции (директива ^include) позволяет записать определения необходимых структур данных и заголовков внешних процедур и функций в некоторый файл, который можно рассмат
ривать как аналог модуля определений в языке Modula-2.
Как уже отмечалось, для реализации работы с сопрограммами в среде Pascal-2 в стиле языка Modula-2 необходимо смоделировать структуру данных Process, процедуры NewProcess, Transfer, Allocate и Deallocate, а также функции Available языка Modula-2.
Аналоги процедур Allocate и Deallocate, а также функции Available имеются в СП Pascal-2 (версии, начиная с 2.1): соответственно это pRinew, р^ dispose и space. Для удобства их целесообразно привести к виду, совпадающему с видом в Modula-2:
Фрагмент 1 •
<*Qnomain») (♦Bnostacksheck*) function pQinewtSIZE : integer) integer; external; procedure pddispose (PTR, SIZE : integer); external; function space : integer; external;
-
procedure Allocate (var PTR : integer, SIZE : integer); external;
procedure Deallocate (P, SIZE : integer); external;
function Available : integer; external;
procedure Allocate;
begi n
PTR:=pdinew(SIZE) end;
procedure Deallocate;
begi n pQdispose
function Available;
begin
Aval 1able:=space end;
В СП Pascal-2 версии 2.0 и ниже процедуры р Ц inew и р й dispose отсутствуют. Тем не менее их можно реализовать самостоятельно, используя пакет PASMAC [6, 7] :
фрагмент
.title p.Qinew
; function pPinew(SIZE : integer) integer; external;
func p9inew,PTR,integer,check=O param SIZE,integer beg i n inc SIZE(sp > bic #l,SIZE(sp)
mov SI ZE(sp) , — (sp>
Jsr рс,ЯЬ70
.globi 0b70
mov (sp)+,PTR(sp)
endpr
; procedure pSdispose (P, SIZE : integer); external;
Рассмотрим теперь реализацию процедур NewProcess и Transfer. При создании новой сопрограммы вызовом процедуры NewProcess в структуру данных Process необходимо поместить информацию о стартовом адресе соответствующей процедуры (не имеющей параметров), начальном значении стека (значение, возвращаемое процедурой Allocate, плюс размер рабочей области процесса, т.к. вершина стека при его заполнении смещается сверху вниз) и размере рабочей области (который обычно определяется опытным путем). При создании сопроцесса начальное содержи
мое регистров г0-г5 для него несущественно. Получение адреса загрузки процедуры в СП Pascal-2 рассмотрено в [9]. Тем не менее, в последующем значения регистров г0-г5 необходимо сохранять и восстанавливать. В [12] предлагается сохранять регистры в стеке, однако это сопряжено с необходимостью отслеживать в стеке как область сохранения сопрограммы, так и локальные переменные. Поэтому сохранять регистры г0-г5 удобнее в самой структуре данных Process. С учетом вышесказанного приводим алгоритм:
' фрагмент 3 !
(*Qnomaiп»)
(•Onostacksheck*) type
ADDRESS = О..65535;
Process = record
SAVEAREA : array CO..51 ot ADDRESS;
PC:=P; <* стартовый адрес процедуры P •)
SP:=STADDR+SIZE-2 <* вершина стека рабочей области •) end end;
Компиляция с ключом Д nostacksheck необходима для отмены проверки переполнения стека, поскольку стек сопроцесса берется из хипа программы.
При передаче управления сопрограмме процедура Transfer должна сохранить содержимое регистров г0-г5, убрать из стека аргументы вызова процедуры Transfer и сохранить после этого значение верхушки стека и адрес возврата в вызвав
шую процедуру. Реализация процедуры Transfer, с учетом вышесказанного, возможна лишь на ассемблере с использованием пакета PASMAC. Следует учесть, что при входе в процедуру Transfer вершина стека указывает на адрес возврата в вызвавший модуль, а над ней находятся второй и первый параметры вызова процедуры Transfer. Реализация процедуры Transfer может быть такой:
! фрагмент 4 1
.title Тгansfer ; рабочие* ячейки: WRi.: .word
WRK1: .нога
; type ; Process = array CO..7) of integer;
; procedure Transferl var SOURCE, DEST : Process ); proc Transfer,check—0
param SOURCE,ADDRESS param DEST,ADDRESS beg i n mov rO,WRK ; сохранить текущее значение г О mov SOURCE(sp),ги ; адрес области сохранения SOURCE
; сохранить в SOURCE регистры г<>-г5 тех WRK,(г О)*
**v г !,(гО)4
OOV г2, <гС> ♦
•, :,.. we "Т . _• . ДрС ООЗбрС: Т,^ . .ЗПОМНИТЬ Б Г1
■: ' .OURCF «цл ументы Tr ansf er
DEST
Проверку правильности реализации механизма сопрограмм можно проверить на контрольном примере из [12]:
-
1 фрагмент 5 '
const MEMREQ = 100; var MAINPRG, Pl, P2 : process; STACK1, STACK1 : integer;
-
I, J : 1nteger;
Xinclude PROSEC; procedure TESTI; begin wri tel n('Первый вход в процедуру TESTI'); Transfer(Pl,MAINPRG);
J:=7;
writeln<'Второй вход в процедуру TESTI ');
Transfer writeln( Третий вход R процедуру TESTI ); Transfer(Pl,MAINPRG) ; end; procedure TEST2; var X : integer; begin writeln('Первый вход в процедуру TEST2'); X: = l; Transfer(Р2,MAINPRG); writelп( Второй вход в процедуру TEST2, Х= ', X, Л-Transfer(Р2,MAINPRG) ; end; begi n Al 1ocate(STACK1,MEMREQ); Al 1ocate(STACK2,MEMREQ, ; NewProcess(TESTI,STACK1,MEMREQ,Pl) NewProcess(TEST2,STACK2,MEMREQ,P2) writeln('Transfer к TESTI'); J: =5; Transfer(MAINPRG, MAINPRG); Transfer(MAINPRG,Pl); writeln('Назад из TESTI'); Transfer(MAINPRG,Pl); writeln('Transfer к TEST2 ' >; Transfer(MAINPRG,Pl); writeln('Назад из TEST2'>; Transfer(MAINPRG,Pl); writeln('Назад из TESTI); Transfer(MAINPRG,p1); writein('В ведущей программе') end. SAVEAREA : array CO..5] of integer; SP : integer; FC : integer; end; procedure NewProcesst procedure PROC; ADR, SIZE : integer; var p : Process ); external; procedure Transfer! var Pl, P2 : Process ); external; procedure Al locate( var P : integer; SIZE : integer ); external ; Если в программах, использующих сопроцессы, применяется аппаратная арифметика с плавающей точкой (сопроцессор с набором команд FPP), то также необходимо сохранять аккумуляторы плавающей арифметики. Поскольку это, с одной стороны, тривиально, а с другой стороны, используется не часто, то сохранение этих аккумуляторов мы не рассматривали. 4, Реализация сопрограмм в СП Pascal-1 На малых микроЭВМ типа ДВК до настоящего времени активно используется СП Pascal-1, которая отличается небольшой потребностью в дисковых ресурсах, хотя и упрощенной реализацией языка Pascal. Практически все вышеуказанные механизмы введения сопрограмм применимы для СП Pascal-1. Так, содержимое файла PROSEC.PAS остается без изменений. Некоторые изменения должны быть внесены в программные модули, т.к. с СП Pascal-1 регистр г5 используется для указателя на область глобальных переменных и не должен изменяться в процессе работы: ! фрагмент 7 ! (* йе+, йа-, fit-, йс .title NewProcee» *) type ADDRESS = О..65535; Process = record SAVEAREA : array CO..51 of ADDRESS; SP,PC : ADDRESS end; procedure NewProcesst P,STADDR, SIZE : ADDRESS; var PROS: Process ); external; procedure NewProcess; begi n with PROC do begin PC:=P; <» стартовый адрес процедуры P *) SP:=STADDR+SIZE-2 (* вершина стека рабочей области *> end end; (* йе+, йа-, fit-, Sc .title Transfer *) procedure Transfer( var SOURCE, DEST : Process ); type Process = array CO..7] of integer; beg i n (*0c mov rO,WRK ; сохранить текущее значение rO mov SOURCE ; сохранить в SOURCE регистры r0-r4 mov WRK,trO) + mov г 1, (rO) + mov r2,(rO)+ mov r3, (rO) + mov r4,(rO)+ ; в вершине стека адрес возврата — запомнить в rl mov sp,r 1 ; убрать из стека SOURCE аргументы Transfer add #6, г 1 (* det, da-, dt-, de .title MEMMAN ♦ > function space : integer; external; function psinew(SIZE : integer) integer; external; procedure psdispose (PTR, SIZE : integer); external; procedure Allocate (var PTR : integer, SIZE : integer); begin PTR:=psinewiSIZE) end; procedure Deallocate (P, SIZE s integer); begi n psdi spose function Available : integer; begin Aval Iables-space end; <♦ Qe+, da-, dt.-, dr. .title psi new *) function pstnew(ST7E : integer) integer; var PTR : integer; begin (♦de inc SIZE(sp) bi c * 1 ,SI ZE(sp) mov SI ZE(sp),-(sp> jsr pc,db7O .glnbl oh 70 mov ») PR! NEW: =PTE: end; procedure psni^uu- IP, SIZE heg i n 'nteger); -. • Or aw SIZE! sp ) , rQ inc rO Die fl , rO mov P(spf , - (sp) Jsr pc,cb?" .globl db72 » ) end.
; сохранить пр
апит.ное значение r 1 , (rO)r