Язык системного программирования
Парадигмы | процедурный , императивный , структурированный |
---|---|
Семья | АЛГОЛ |
Впервые появился | 1972 год |
Под влиянием | |
АЛГОЛ 60 , ЭСПОЛ | |
Под влиянием | |
ЗСПЛ, Микро-СПЛ, Действие! |
Язык системного программирования , часто сокращаемый до SPL , но иногда известный как SPL/3000 , был процедурно-ориентированным языком программирования , написанным Hewlett-Packard для HP 3000 линейки миникомпьютеров и впервые представленным в 1972 году. SPL использовался для написания основных операционных систем HP 3000. система , Многопрограммный исполнитель (MPE). Подобные языки на других платформах обычно назывались языками системного программирования , что приводило к путанице.
Первоначально известный как язык программирования Alpha Systems , названный в честь проекта разработки, в результате которого была создана серия 3000, SPL был разработан с учетом преимуществ конструкции процессора Alpha на основе стека . Он создан по образцу ESPOL , аналогичного языка, производного от ALGOL , используемого в Burroughs B5000 мэйнфреймах , который также повлиял на ряд языков 1960-х годов, таких как PL360 и JOVIAL .
В середине 1970-х годов успех систем HP привел к появлению ряда ответвлений SPL. Примеры включают ZSPL для процессора Zilog Z80 и Micro-SPL для Xerox Alto . Более поздний вдохновленный Action! для 8-битных компьютеров Atari , что было довольно успешным. Последний более точно следовал синтаксису Паскаля , теряя некоторые особенности SPL.
SPL широко использовался во время существования оригинальной 16-битной версии платформы HP 3000. В 1980-х годах HP 3000 и MPE были перереализованы в эмуляторе, работающем на PA-RISC на базе платформах HP 9000 . HP продвигала Паскаль как предпочтительный системный язык на PA-RISC и не предоставила компилятор SPL. Это вызвало проблемы с обслуживанием кода сторонние компиляторы , и для удовлетворения этой потребности были введены SPL.
История
[ редактировать ]Hewlett-Packard представила свои первые миникомпьютеры серии HP 2100 в 1967 году. Первоначально машины были разработаны сторонней командой, работавшей на Union Carbide , и предназначались в основном для использования в промышленных системах управления, а не на более широком рынке обработки данных. В HP увидели в этом естественное соответствие существующему бизнесу по производству приборов и первоначально предложили его этим пользователям. машины Несмотря на это, компания HP обнаружила, что соотношение цены и производительности делает ее все более успешной на бизнес-рынке. [1] [2]
В этот период концепция разделения времени становилась популярной, особенно когда стоимость основной памяти упала и системы стали поставляться с большим объемом памяти. В 1968 году HP представила комплексную систему, состоящую из двух машин серии 2100, работающих под управлением HP Time-Shared BASIC , которая обеспечивала полноценную операционную систему , а также язык программирования BASIC . Эти двухмашинные системы, известные под общим названием HP 2000, сразу же имели успех. [3] HP BASIC пользовался большим влиянием на протяжении многих лет, и его синтаксис можно увидеть во многих микрокомпьютерных BASIC, включая Palo Alto TinyBASIC , Integer BASIC , North Star BASIC , Atari BASIC и других.
Дизайнеры HP начали задаваться вопросом: «Если мы сможем создать такую хорошую систему разделения времени, используя такой старый компьютер, как 2116, подумайте, чего мы могли бы достичь, если бы разработали свой собственный компьютер». [4] С этой целью в 1968 году компания начала собирать большую команду для разработки новой архитектуры среднего размера. В число новых членов команды входили те, кто работал над Burroughs и IBM мэйнфреймами , и получившиеся в результате концепции сильно напоминали весьма успешную систему Burroughs B5000 . В B5000 использовался стековый процессор, который упрощал мультипрограммирования , и та же самая архитектура была выбрана для новой концепции HP. реализацию [5]
Были рассмотрены две реализации: 32-битная машина масштаба мэйнфрейма, известная как Omega, и 16-битная конструкция, известная как Alpha. Почти все усилия были направлены на Omega, но в июне 1970 года Omega была отменена. Это привело к обширному перепроектированию Alpha, чтобы отличить ее от 2100-х, и в конечном итоге появились планы по еще более агрессивному дизайну операционной системы. Omega намеревалась работать в пакетном режиме и использовать компьютер меньшего размера, «интерфейсный интерфейс», для обработки взаимодействия с пользователем. Это была та же концепция управления, что и в серии 2000 года. Однако еще одного-2000 года для «Альфы» было недостаточно, и было принято решение иметь единую операционную систему для пакетной, интерактивной и даже работы в реальном времени . [5]
Чтобы это работало, требовалась усовершенствованная конструкция компьютерной шины с обширным прямым доступом к памяти (DMA) и современная операционная система (ОС), обеспечивающая быструю реакцию на действия пользователя. B5000 был также уникален для своего времени тем, что его операционная система и основные утилиты были запрограммированы на высокого уровня ESPOL языке . ESPOL был производным от языка ALGOL, настроенным для работы на B5000. Эта концепция имела большое влияние в 1960-х годах и привела к появлению новых языков, таких как JOVIAL , PL/360 и BCPL . Команда HP решила, что они также будут использовать язык, производный от ALGOL, для работы в своих операционных системах. Похожий язык HP первоначально был известен как язык программирования Alpha Systems. [5]
На разработку Alpha ушло несколько лет, прежде чем она появилась в 1972 году под названием HP 3000. Машина пробыла на рынке всего несколько месяцев, прежде чем стало ясно, что она просто работает неправильно, и HP была вынуждена отозвать все уже проданные модели 3000. Он был повторно представлен в конце 1973 года, и большинство его проблем было исправлено. Серьезное обновление всей системы, машины CX и работающего на ней MPE-C изменило ее имидж, и 3000 стал еще одним крупным успехом во второй половине 1970-х годов. [5]
Этот успех сделал SPL почти таким же распространенным, как BASIC серии 2000 года, и, как и этот язык, SPL привел к появлению ряда версий для других платформ. Среди них следует выделить Micro-SPL, версию, написанную для рабочей станции Xerox Alto . Первоначально эта машина использовала BCPL в качестве основного языка, но неудовлетворенность его производительностью побудила Генри Бейкера разработать нерекурсивный язык, который он реализовал вместе с Клинтоном Паркером в 1979 году. [6] Затем Клинтон модифицировал Micro-SPL, чтобы создать Action! для 8-битных компьютеров Atari в 1983 году. [7]
HP переработала систему HP 3000 на чипсете PA-RISC, используя новую версию операционной системы, известную как MPE/iX. MPE/iX имел два режима: в «собственном режиме» он запускал приложения, перекомпилированные для PA-RISC с использованием более новых компиляторов Pascal, а в «совместимом режиме» он мог запускать все существующее программное обеспечение посредством эмуляции. HP не предоставила компилятор собственного режима для MPE/iX, поэтому перенести существующее программное обеспечение на новую платформу было непросто. Чтобы удовлетворить эту потребность, Allegro Consultants написали SPL-совместимый язык под названием «SPLash!». который можно скомпилировать в исходный код HP 3000 для запуска в эмуляторе или в собственном режиме. Это открыло путь переноса существующего программного обеспечения SPL. [8]
Язык
[ редактировать ]Основной синтаксис
[ редактировать ]SPL обычно следует синтаксическим соглашениям ALGOL 60 и будет знаком каждому, кто имеет опыт работы с ALGOL или его потомками, такими как Pascal и Modula-2 . Как и в этих языках, операторы программы могут занимать несколько физических строк и заканчиваться точкой с запятой. Комментарии обозначаются значком COMMENT
ключевое слово или заключив текст комментария в << и >>. [9]
Операторы группируются в блоки с помощью BEGIN и END, хотя, как и в Паскале, за END программы должна следовать точка. Программа в целом окружена BEGIN и END., аналогично Паскалю, но без ключевого слова PROGRAM или аналогичного оператора вверху. [10] Причина этого в том, что SPL позволяет использовать любой блок кода как программу самостоятельно или скомпилировать в другую программу, которая будет действовать как библиотека. Создание кода в виде программы или подпрограммы не было частью самого языка, а осуществлялось путем размещения $CONTROL SUBPROGRAM
директива компилятора в верхней части файла. [11]
Язык обеспечил INTRINSIC
ключевое слово, обеспечивающее простой метод объявления внешних процедур, что позволяет программисту не объявлять типы и порядок параметров процедур. Все доступные пользователю объявления системных служб (такие как файловая система, обработка процессов, связь и т. п.) были доступны через этот механизм, и пользователи также могли добавлять свои собственные объявления процедур в системный файл. INTRINSIC
список. Это похоже на механизм #include языка C, но более усовершенствованный и узкий.
В отличие от Паскаля, где PROCEDURE
и FUNCTION
были отдельными концепциями, SPL использует более похожий на C подход, где любые PROCEDURE
может иметь префикс типа, чтобы превратить его в функцию. В соответствии с синтаксисом других языков, подобных АЛГОЛу, типы параметров перечислялись после имени, а не его части. Например: [12]
INTEGER PROCEDURE FACT(N); VALUE N; INTEGER N;
Объявляет функцию FACT, которая принимает значение N, являющееся целым числом. VALUE
указывает, что эта переменная является «передаваемой по значению», и поэтому изменения в ней внутри процедуры не будут видны вызывающей стороне. [13] Процедура устанавливает возвращаемое значение с помощью оператора присваивания ее имени:
FACT := expression;
Несмотря на неодобрение, АЛГОЛ и Паскаль позволяли маркировать код, используя начальное имя, оканчивающееся двоеточием, которое затем можно было использовать для целей циклов и GO TO
заявления. Одно незначительное отличие состоит в том, что SPL требовал, чтобы имена меток были объявлены в разделе переменных с использованием LABEL
ключевое слово. [14]
SPL дополнил эту концепцию ENTRY
оператор, который позволил определить эти метки как «точки входа», доступ к которым можно получить из командной строки. Метки, указанные в операторах ввода, были доступны операционной системе и могли быть вызваны из команды RUN. Например, можно написать программу, содержащую строковые функции для преобразования в верхний или нижний регистр, а затем предоставить для этих двух точек ВХОДА. Это можно вызвать из командной строки как RUN $STRINGS,TOUPPER
. [15]
Типы данных
[ редактировать ]SPL наиболее заметно отличается от ALGOL тем, что его типы данных очень машинно-специфичны и основаны на 16-битном формате слов с прямым порядком байтов в 3000 . [10]
The INTEGER
type — это 16-битный знаковый тип с 15 битами значения и младшим битом в качестве знака. DOUBLE
представляет собой 32-битное целое число, а не тип с плавающей запятой. REAL
представляет собой 32-битное значение с плавающей запятой, 22 бита для мантиссы и 9 для экспоненты, а LONG
представляет собой 64-битное значение с плавающей запятой с 54 битами мантиссы и 9 битами экспоненты. [16]
BYTE
используется для обработки символов, состоящих из 16-битного машинного слова, содержащего один 8-битный символ в младших битах. Массивы типа BYTE упаковывают два 8-битных символа в 16-битное машинное слово. LOGICAL
— это 16-битный целочисленный тип без знака, который при использовании в условном выражении возвращает true, если младший значащий бит равен 1, и false в противном случае. Целочисленные арифметические операции без знака могут выполняться с ЛОГИЧЕСКИМИ данными, при этом любое переполнение игнорируется. Не существует эквивалента PACKED
модификатор, как в Паскале, поэтому LOGICAL
несколько расточительно тратит память [17] когда используется только для хранения одной двоичной цифры, хотя SPL предлагает в качестве альтернативы манипулирование битовой строкой.
Как и в C, данные слабо типизированы , ячейки памяти и хранилище переменных представляют собой смешанные понятия, и можно получить доступ к значениям непосредственно через их местоположения. Например, код:
INTEGER A,B,C LOGICAL D=A+2
определяет три 16-битные целочисленные переменные: A, B и C, а затем ЛОГИЧЕСКОЕ, также 16-битное значение. =
, как и в Паскале, означает «эквивалентно», а не «получает значение», в котором используется :=
в алголоподобных языках. Таким образом, вторая строка гласит: «объявите переменную D, которая находится в той же ячейке памяти, что и A+2», что в данном случае также является местоположением переменной C. Это позволяет считывать одно и то же значение как целое число через C или логическое через Д. [18]
Этот синтаксис может показаться странным современным читателям, где память обычно представляет собой черный ящик , но он имеет ряд важных применений в системном программировании, где определенные области памяти содержат значения из базового оборудования. В частности, он позволяет определить переменную, указывающую на начало таблицы значений, а затем объявить дополнительные переменные, указывающие на отдельные значения в таблице. Если расположение таблицы изменится, должно измениться только одно значение — начальный адрес, и все отдельные переменные автоматически последуют за ним в своих соответствующих относительных смещениях. [18]
Указатели были объявлены путем добавления POINTER
модификатор любого объявления переменной и местоположение в памяти переменной, разыменованной с помощью @
. Таким образом INTEGER POINTER P:=@A
объявляет указатель, значение которого содержит адрес переменной A, а не значение A. [19] @
может использоваться с любой стороны задания; @P:=A
помещает значение A в P, что, вероятно, приводит к висячему указателю , @P:=@A
заставляет P указывать на A, в то время как P:=A
помещает значение A в то место, на которое в данный момент указывает P. [20]
Подобным образом SPL включает поддержку массивов типа C, в которой индексная переменная представляет собой смещение на количество слов от ячейки памяти, установленной для исходной переменной. В отличие от C, SPL предоставлял только одномерные массивы и использовал круглые скобки, а не скобки. [21] Переменные также могут быть объявлены GLOBAL
, в этом случае для них не выделялась локальная память и предполагалось, что хранилище объявлено в другой библиотеке. [22] Это отражает extern
ключевое слово в C.
Литералы могут быть указаны с различными суффиксами, а литералы без суффикса считаются INTEGER
. Например, 1234
будет интерпретироваться как INTEGER
, пока 1234D
был DOUBLE
. E
обозначал REAL
и L
а LONG
. [23] Строковые константы ограничивались двойными кавычками, а двойные кавычки внутри строки экранировались второй двойной кавычкой. [24]
В объявлениях переменных могут использоваться константы для определения начального значения, как в INTEGER A:=10
. Обратите внимание на использование присваивания вместо is-a. Кроме того, у SPL была EQUATE
Ключевое слово, которое позволяло определить текстовую строку как переменную, а затем заменять любые экземпляры этой переменной в коде строкой-литералом во время компиляции. [25] Это похоже на const
ключевое слово в C.
Сегментация памяти
[ редактировать ]Классический HP 3000 организовал физическую память в 1, 2, 4, 8 или 16 банков по 64 КБ (65536) 16-битных слов (128 КБ). Код (общий, неизменяемый) и данные были отделены друг от друга и хранились в сегментах переменной длины длиной до 32 000 слов каждый. Внутри процесса адреса данных, такие как указатели, представляли собой 16-битные смещения от базового регистра (известного как DB) или относительные смещения от регистра указателя (Q или S), что приводило к появлению действительного адреса в области данных процесса (называемой адресом). куча). Хотя система в основном ориентирована на 16-битные слова, она поддерживала адресацию отдельных байтов в массиве, используя адрес слова, в котором хранился байт, смещенный влево на 1 бит, а затем добавляя 0 для доступа к верхнему байту или 1 для младшего байта. Таким образом, адреса байтов были отдельными и отличными от адресов слов, а интерпретация адреса была чисто контекстной. Это оказалось весьма проблематичным и стало источником многочисленных ошибок как в системном, так и в пользовательском коде. Необходимо было позаботиться о том, чтобы адреса байтов рассматривались как 16-битные беззнаковые (то есть типа LOGICAL) при их использовании, например, в вычислениях длины, поскольку в противном случае адрес байта 2^16 или более будет рассматриваться как 2s-. дополняют знаковое значение, что приводит к ошибочному вычислению длин или смещений.
Отдельный процесс имел доступ к 254 сегментам кода длиной до 32 000 слов каждый. Сегменты кода были разделены на два домена: первые 191 были «системными» сегментами, общими для всех процессов, а остальные 63 были «пользовательскими» сегментами, общими для всех, запускающих одну и ту же программу. При передаче управления указывается либо номер процедуры внутри текущего сегмента, либо номер внешнего сегмента и номер процедуры внутри него. Небольшая таблица в конце сегмента содержала адрес точки входа для процедуры.
Код процесса обрабатывал данные в стеке, один частный сегмент которого также имел размер до 32 тысяч слов. В отличие от стеков в других архитектурах, стек HP 3000 использовался для глобальных переменных процессов, сохранения состояния, локальных переменных процедур (поддержка вложенных вызовов и повторного входа), а также числовых вычислений/оценок. Операционная система предоставляла средства для доступа к дополнительным сегментам данных в памяти (не стековым), но они не были изначально адресованы набором команд, и поэтому программа отвечала за перемещение данных из и в такие «дополнительные сегменты данных» по мере необходимости. .
SPL включал в себя множество систем поддержки, позволяющих легко сегментировать программы, а затем делать эту сегментацию относительно невидимой в коде. Основной механизм заключался в использовании $CONTROL SEGMENT=asegmentname
директива компилятора , определяющая, в какой сегмент должен быть помещен следующий код. По умолчанию было MAINLINESEG
, но программист мог добавить любое количество дополнительных именованных сегментов для организации кода в блоки. [26]
Другие особенности
[ редактировать ]SPL включал функцию «извлечения битов», которая позволяла упростить работу с битами . Доступ к любому биту или строке битов в слове можно получить с помощью .(x:y)
синтаксис, где x и y были позициями начального и конечного битов от 0 до 15. (Примечательно, что x и y должны быть константами, известными во время компиляции.) Таким образом, A.(8:15)
вернул младший байт слова, хранящего A. [27] Этот формат можно использовать для разделения и объединения битов по мере необходимости. Кроме того, были предусмотрены дополнительные операции для сдвигов и поворотов, которые можно было применять к любой переменной с помощью &
, например A:=A & LSR(3)
. [28]
Пример
[ редактировать ]Эта простая программа из версии справочного руководства 1984 года демонстрирует большинство возможностей языка SPL. [11]
Программа в целом разграничена между BEGIN
и END.
. Он начинается с определения ряда глобальных переменных A, B и C, определяет одну процедуру, а затем вызывает ее двадцать раз. Обратите внимание, что процедура не имеет собственных BEGIN и END, поскольку она содержит только одну строку реального кода. X:=X*(Y+Z);
тот INTEGER X,Y,Z
не считается частью самого кода, он указывает тип трех параметров, передаваемых в строке выше, и считается частью этой строки. [11]
BEGIN INTEGER A:=0, B, C:=1; PROCEDURE N(X,Y,Z); INTEGER X,Y,Z; X:=X*(Y+Z); FOR B:=1 UNTIL 20 DO N(A,B,C); END.
Ссылки
[ редактировать ]Цитаты
[ редактировать ]- ^ Лейбсон 2017 .
- ^ «История цифровой вычислительной машины 2116А» . ХП .
- ^ «Компьютеры Хьюлетт/Паккард» .
2000A была первой системой таймшера HP 2000, представленной на рынке ок. 1969 год
- ^ Грин 2004 .
- ^ Перейти обратно: а б с д Эдлер 1995 .
- ^ Бейкер, Генри; Паркер, Клинтон (сентябрь 1979 г.). «Микро-СПЛ» (PDF) .
- ^ Паркер, Клинтон (31 декабря 2015 г.). «Интервью ANTIC 111, Клинтон Паркер, действие!» (подкаст). Беседовал Рэнди Киндиг.
- ^ «SPLash! Компилятор SPL в собственном режиме для MPE/iX» . Консультанты Аллегро. 1 января 2004 г.
- ^ SPL 1984 , стр. 1.2, 1.3.
- ^ Перейти обратно: а б СПЛ 1984 , с. 1.1.
- ^ Перейти обратно: а б с СПЛ 1984 , стр. 1.5.
- ^ SPL 1984 , стр. 1.11.
- ^ SPL 1984 , стр. 7–4.
- ^ SPL 1984 , стр. 3.15.
- ^ SPL 1984 , стр. 1.13, 1.14.
- ^ SPL 1984 , стр. 2.1–2.3.
- ^ SPL 1984 , стр. 2.4.
- ^ Перейти обратно: а б SPL 1984 , стр. 3.2.
- ^ SPL 1984 , стр. 2.13.
- ^ SPL 1984 , стр. 4.4.
- ^ SPL 1984 , стр. 2.12.
- ^ SPL 1984 , стр. 3.6.
- ^ SPL 1984 , стр. 2.6.
- ^ SPL 1984 , стр. 2.11.
- ^ SPL 1984 , стр. 3.18.
- ^ SPL 1984 , стр. 1.8.
- ^ SPL 1984 , стр. 4.6.
- ^ SPL 1984 , стр. 4.9.
Библиография
[ редактировать ]- Эдлер, Кристофер (ноябрь 1995 г.). «Самый сильный замок: взлет, падение и взлет HP 3000» . Аналитическая машина . 3 (1). ISSN 1071-6351 . Архивировано из оригинала 3 февраля 2002 года.
- Грин, Боб (2004). HP3000 Эволюция . Робель.
- Лейбсон, Стив (2017). «HP: случайно созданная компьютерная компания» . HP9825.COM .
- Справочное руководство по языку системного программирования (PDF) . Хьюлетт-Паккард. Февраль 1984 года.