Приведённые программы могут использоваться как простое средство для выполнения функций ввода-вывода в программах, написанных на языке ассемблера. Эти программы можно применять или для ввода и печати чисел, или для ввода и печати символьных строк. Для включения в программу пользователя их можно скопировать и выполнить их ассемблирование вместе с программой пользователя. Можно поступить и иначе: выполнить ассемблирование программ ввода-вывода только один раз, а их подключение к программам пользователя осуществлять на этапе компоновки, связывая эти программы через глобальные имена.
Всего для выполнения функций ввода-вывода используется пять подпрограмм, а именно IOINIT, RNUM, PNUM, RLINE и PLINE. Все они вызываются с помощью инструкции JSB. Ниже дано описание функций, выполняемых этими подпрограммами.
Подпрограмма IOINIT используется для установки начальных значений в четырёх других подпрограммах ввода-вывода. Она вызывается только один раз, но при этом должна быть вызвана перед тем, как будет использована какая-либо из этих других подпрограмм. Вызов подпрограммы осуществляется следующим образом:
JSB IOINIT
Подпрограмма IOINIT возвращает управление, сохраняя содержимое всех регистров. Кроме того, что она позволяет выполнять другие подпрограммы из данного набора, явным результатом её работы является печать сообщения об её успешном завершении.
Подпрограмма RNUM предназначается для ввода шестнадцатеричного числа из файла системного ввода. Преобразованное во внутреннее представление число помещается в регистр R0. Содержимое всех других регистров не изменяется. При работе в интерактивном режиме на терминал выдаётся запрос "ВВЕДИТЕ ШЕСТНАДЦАТЕРИЧНОЕ ЧИСЛО - ". Обращение к подпрограмме следующее:
JSB RNUM результат возвращается в R0
Подпрограмма PNUM служит для выполнения печати содержимого регистра R0 (содержимое рассматривается как длинное слово) в шестнадцатеричном и десятичном виде. Содержимое всех регистров не изменяется. Обращение к подпрограмме осуществляется следующим образом:
загрузить число в R0 JSB PNUM
Подпрограмма RLINE предназначена для чтения строки символов в коде ASCII из файла системного ввода. Введённые символы помещаются в массив, находящийся в программе пользователя. При вызове подпрограммы ей необходимо передать адрес байтового массива, в который будет помещена строка символов, и длину этого массива. Адрес в формате длинного слова должен находиться в регистре R0, а длина массива в формате слова помещается в регистр R1. После того, как подпрограмма RLINE передаёт управление обратно, в массиве будут находиться все символы, присутствовавшие во вводимой строке, а в регистре R1 будет содержаться в формате слова число, соответствующее количеству в действительности введённых символов. Это число может изменяться от 0 до заданной длины массива, но не может превышать заданную длину массива. В регистре R0 будет находиться в формате слова код ошибки. Если ошибок не было, то регистр R0 будет содержать число 1. Наличие в регистре любого другого числа означает, что произошла ошибка. Наиболее вероятными являются ошибки, связанные с тем, что длина буфера слишком мала, чтобы вместить всю строку, или же была предпринята попытка продолжить ввод после того, как был встречен признак конца вводимых данных. Содержимое всех других регистров не изменяется. Последовательность действий при вызове подпрограммы RLINE приведена ниже.
загрузить адрес буфера в R0 предельную длину буфера в R1 JSB RLINE R0 содержит код ошибки R1 содержит число введённых символов
Подпрограмма PLINE используется для вывода на печать в файл системного вывода строки текста в коде ASCII. В регистр R0 должен быть помещён адрес массива символов, а регистр R1 должен содержать в формате слова число символов в этом массиве. Содержимое всех регистров сохраняется. Так как подпрограмма PLINE сопровождает вывод каждой строки управляющими символами "Возврат каретки" и "Перевод строки", то в выводимой строке эти символы не должны присутствовать, если только нет необходимости вывести дополнительные строчки. Последовательность вызова для подпрограммы PLINE даётся ниже.
загрузить адрес буфера в R0 число символов в R1 JSB PLINE
Для использования программ ввода-вывода в программе пользователя приведённые ниже исходные тексты программ могут быть помещены между последней строчкой текста программы пользователя и директивой .END. Программы сопровождаются комментариями, поясняющими их действие. Однако предполагается, что не всё будет полностью понятно, пока не будут прочитаны гл. 1-11. Для ускорения ввода текста программ можно опустить комментарии. Программы могут быть ассемблированы как отдельный программный модуль, а полученный в результате ассемблирования объектный файл может быть скомпонован с основной программой.
RNUMBUFSIZ=80 ;УСТАНОВИТЬ ДЛИНУ БУФЕРОВ 80 PNUMBUFSIZ=80 .PSECT IOROUTINE,LONG ;FAB И RAB ВЫРОВНЕНЫ RNUMFILE: $FAB FNM=<SYS$INPUT> ;НА ГРАНИЦУ ДЛИННОГО СЛОВА PNUMFILE: $FAB FNM=<SYS$OUTPUT>,RAT=<CR> RNUMIREC: $RAB FAB=RNUMFILE,UBF=RNUMBUF,USZ=RNUMBUFSIZ,- PBF=RNUMPRO,PSZ=RNUMPROL-RNUMPRO,ROP=<PMT> PNUMOREC: $RAB FAB=PNUMFILE,RBF=PNUMOUT RLINEREC: $RAB FAB=RNUMFILE,- PBF=RLINEPRO,PSZ=RLINEPROL-RLINEPRO,ROP=<PMT> PLINEREC: $RAB FAB=RNUMFILE PNUMTEMP: .BLKL 1 ;ВРЕМЕННАЯ ПАМЯТЬ И БУФЕРЫ PNUMOUT: .BLKB PNUMBUFSIZ RNUMBUF: .BLKB RNUMBUFSIZ ;СИМВОЛЬНЫЕ СТРОКИ И ДЕСКРИПТОРЫ PNUMSTR: .ASCID "ВЫВОД !XL(ШЕСТНАДЦАТЕРИЧНОЕ) !SL(ДЕСЯТИЧНОЕ)" IOINITSTR: .ASCID "ВВОД И ВЫВОД ИНИЦИАЛИЗИРОВАНЫ !%D" RNUMPRO: .ASCII "ВВЕДИТЕ ШЕСТНАДЦАТЕРИЧНОЕ ЧИСЛО - " RNUMPROL: RLINEPRO: .ASCII "ВВЕДИТЕ СТРОКУ - " RLINEPROL: PNUMDES: .LONG PNUMBUFSIZ .LONG PNUMOUT ; ПРОГРАММА ИНИЦИАЛИЗАЦИИ IOINIT:: PUSHR #^M<R0,R1> ;СОХРАНИТЬ СОДЕРЖИМОЕ РЕГИСТРОВ $OPEN FAB=RNUMFILE ;ОТКРЫТЬ ФАЙЛ ВВОДА $CREATE FAB=PNUMFILE ;ОТКРЫТЬ ФАЙЛ ВЫВОДА $FAO_S CTRSTR=IOINITSTR,OUTBUF=PNUMDES,- ;ФОРМАТ OUTLEN=PNUMOREC+RAB$W_RSZ,P1=$0 ;СООБЩЕНИЯ $CONNECT RAB=PNUMOREC ;ПОДКЛЮЧИТЬ RAB СООБЩЕНИЙ $PUT RAB=PNUMOREC ;ПЕЧАТЬ СООБЩЕНИЯ ОБ ИНИЦИАЛИЗАЦИИ POPR #^M<R0,R1> ;ВОССТАНОВИТЬ РЕГИСТРЫ RSB ;ВОЗВРАТ ; ПРОГРАММА ПЕЧАТИ ЧИСЛА PNUM:: PUSHR #^M<R0,R1> ; СОХРАНИТЬ СОДЕРЖИМОЕ РЕГИСТРОВ MOVL R0,PNUMTEMP ; ПОЛУЧИТЬ И ПРЕОБРАЗОВАТЬ ЧИСЛО $FAO_S CTRSTR=PNUMSTR,OUTBUF=PNUMDES,OUTLEN=PNUMOREC+RAB$W_RSZ,- P1=PNUMTEMP,P2=PNUMTEMP $CONNECT RAB=PNUMOREC ;ПОДКЛЮЧИТЬ RAB ВЫВОДА $PUT RAB=PNUMOREC ;И НАПЕЧАТАТЬ ЧИСЛО POPR #^M<R0,R1> ;ВОССТАНОВИТЬ РЕГИСТРЫ RSB ;ВОЗВРАТ ; ПРОГРАММА ВВОДА ЧИСЛА RNUM:: PUSHR #^M<R1> ;СОХРАНИТЬ РЕГИСТР R1 $CONNECT RAB=RNUMIREC ;ПОДКЛЮЧИТЬ RAB ВВОДА $GET RAB=RNUMIREC ;ВВЕСТИ ЧИСЛО CLRL R0 ;ОЧИСТИТЬ РЕГИСТР ПРЕОБРАЗОВАНИЯ MOVAB RNUMBUF,R1 ;УКАЗАТЕЛЬ НА БУФЕР ЧИСЛА 10$: DECW RNUMIREC+RAB$W_RSZ ;УМЕНЬШИТЬ СЧЁТЧИК СИМВОЛОВ BLSS 30$ ;ЗАКОНЧИТЬ, ЕСЛИ В СЧЁТЧИКЕ 0 ASHL #4,R0,R0 ;УМНОЖИТЬ НА 16 SUBB2 #48,(R1) ;ПРЕОБРАЗОВАТЬ В ДВОИЧНОЕ ЧИСЛО СМРВ (R1),#10 ;БОЛЬШЕ ЧЕМ 10? BLSS 20$ ;НЕТ SUBB2 #65-48-10,(R1) ;ДА, ПРЕОБРАЗОВАТЬ ASCII "А" В 10 20$: BISB (R1)+,R0 ;ДОБАВИТЬ К ПОЛУЧЕННОМУ ЧИСЛУ BRB 10$ ;ПОВТОРИТЬ ДЛЯ ОСТАВШИХСЯ ЦИФР 30$: POPR #^M<R1> ;ВОССТАНОВИТЬ РЕГИСТР R1 RSB ;ВОЗВРАТ ; ПРОГРАММА ВВОДА СТРОКИ RLINE:: MOVL R0,RLINEREC+RAB$L_UBF ;УСТАНОВИТЬ АДРЕС БУФЕРА MOVW R1,RLINEREC+RAB$W_USZ ;И ЕГО ПРЕДЕЛЬНУЮ ДЛИНУ $CONNECT RAB=RLINEREC ;ПОДКЛЮЧИТЬ RAB $GЕТ RAB=RLINEREC ;ВВЕСТИ СТРОКУ MOVZWL RLINEREC+RAB$W_RSZ,R1 ;ВЕРНУТЬ ДЛИНУ ВВЕДЁННОЙ СТРОКИ RSB ;И КОД ОШИБКИ В R0 ;ПРОГРАММА ПЕЧАТИ СТРОКИ PLINE:: PUSHR #^M<R0,R1> ;СОХРАНИТЬ СОДЕРЖИМОЕ РЕГИСТРОВ MOVL R0,PLINEREC+RAB$L_RBF ;ПОЛУЧИТЬ АДРЕС БУФЕРА MOVW R1,PLINEREC+RAB$W_RSZ ;И ДЛИНУ СТРОКИ $CONNECT RAB=PLINEREC ;ПОДКЛЮЧИТЬ RAB ВЫВОДА $PUT RAB=PLINEREC ;НАПЕЧАТАТЬ СТРОКУ POPR #^M<R0,R1> ;ВОССТАНОВИТЬ РЕГИСТРЫ RSB ;ВОЗВРАТ
< НАЗАД | ОГЛАВЛЕНИЕ | ВПЕРЁД > |