Новое знакомство с RWD и WWD

 

{toc_noshowall}Теперь нам известны все подробности работы макрокоманд RWD и WWD. Мы проследили все шаги преобразования чисел из кодов EBCDIC в двоичную форму, выполняемые макро RWD. Мы изучили также и обратный процесс, для реализации которого служит макро WWD. Фактически, включая в программу макро RWD, мы включали в нее команды обращения к подпрограмме, выполняющей необходимые преобразования и возвращающей число в окончательной двоичной форме. Макро WWD обращается к другой части этой же подпрограммы, производящей обратные преобразования (из двоичной формы в коды EBCDIC) и выполняющей печать строки из полученных символов. В дальнейшем мы уже не должны пользоваться этими макро. Материал данной главы может на первый взгляд показаться несколько сложным, однако постепенно вы добьетесь полного автоматизма в выполнении рассмотренных преобразований при условии, конечно, что вы действительно поняли разницу между различными формами представления данных.

 

Для того чтобы у вас сложилось правильное мнение о назначении данной главы, рассмотрим несколько примеров. На рис. 15.7 приведена программа, выполняющая считывание карты с помощью команды RCD. Считывание производится в область CARDIN. Предполагается, что образ введенной карты содержит выровненное по правой границе 12-значное десятичное число, которое может быть снабжено алгебраическим знаком. На карте число располагается в колонках 5—16. Программа производит поиск первого отличного от пробела символа. Если этим символом является минус, в знаковую зону записывается код D. Если первым символом является плюс, то его код заменяется кодом пробела для обеспечения возможности правильной упаковки командой PACK. Все пробелы воспринимаются как нули. Отметим, что упаковка производится сразу в двойное слово, так как преобразование в двоичную форму мы хотим выполнить с помощью команды CVB. Отметим также, что программа предусматривает возможность того, что все символы числа являются пробелами. В этом случае получается нулевой результат. Получившееся двоичное число помещается в регистр 7. Попробуйте проследить выполнение подобных преобразований для выбранных вами исходных данных.

Рис. 15.7. Программа чтения перфокарт и преобразования десятичного целого, отперфорированного в колонках 5—16, в двоичное представление с помещением результата в регистр 7.

Рис. 15.8. Программа чтения перфокарт, содержащих восемь 10-значных десятичных чисел каждая, преобразования каждого числа в двоичное представление и записи результатов в последовательные полные слова памяти.

Теперь мы в состоянии использовать собственные форматы данных. В частности, числовые данные можно теперь набивать на карты, начиная с любой позиции и в любом формате. Можно также более полно использовать перфокарты, т. е. набивать на них больше чисел. На рис. 15.8 приведена программа, производящая считывание карты в область INPUT. Карта содержит восемь десятизначных целых в формате, описанном в предыдущем примере. Программа осуществляет последовательное преобразование чисел в двоичную форму и так же последовательно записывает их одно за другим в область NMBRS.

Заметим, что между программами рис. 15.7 и рис. 15.8 существует большое сходство.

Наконец, рассмотрим то, что при описании RWD было названо свободным форматом. Вводимое число может располагаться в любом месте карты, содержать от одной до девяти цифр и начинаться кодом знака. Внутри себя число не может содержать пробелов или кодов, отличных от кодов цифр. Это условие введено для обеспечения возможности фиксации начала и конца числа. Считается, что число начинается с первого отличного от пробела символа. Между собой на карте числа разделяются пробелами. Появление пробела свидетельствует о конце числа.

Рис. 15.9. Преобразование десятичных чисел, заданных на перфокартах в свободном формате, в двоичное представление.

Заглядывая немного вперед, предположим, что, просматривая образ карты, мы определили адрес начала и адрес конца числа. После получения зонного формата необходимо произвести упаковку. Но что следует указать в качестве длины второго операнда? Вообще говоря, длина в байтах второго операнда должна быть равна увеличенной на 1 разности между адресами конца и начала числа. То есть фактически необходимо выполнить команду PACK, значение длины второго операнда которой становится известно только в процессе выполнения программы.

Лучшим способом изменения содержимого поля длины в процессе выполнения программы является использование команды EX (Execute— ВЫПОЛНИТЬ). По команде ЕХ происходит выполнение одной команды, находящейся по указываемому адресу.

EX R1,D2(X2,B2)

EXecute

Выполнить команду по адресу D2 + (X2) + (B2)

После выполнения подчиненной команды работа по программе продолжается в обычном порядке. Этот порядок может быть нарушен только в случае, когда адресуемая команда ЕХ является командой передачи управления. При выполнении команды ЕХ содержимое последних 8 разрядов регистра R1 логически складывается с содержимым разрядов 8—15 подчиненной команды. Результат логического сложения не записывается в память, но команда по адресу D2+(B2)+(X2) выполняется именно так, как если бы запись была произведена. В командах формата SS биты 8—15 представляют поле длины. Фактически при выполнении таких команд в качестве содержимого поля длины используется результат логического сложения.

Существует одно ограничение на команду, адресуемую в команде ЕХ: она не может быть также командой ЕХ. Таким образом, с помощью команды ЕХ можно производить модификацию непосредственных операндов команд формата SI, условий в командах условного перехода, номеров регистров в командах формата RR и т. д. Вероятно, вы уже встречались с задачами, в которых было бы удобно производить пересылки единиц информации меняющейся длины без использования циклов.

На рис. 15.9 приведена программа, использующая команду ЕХ для решения возникшей проблемы. Первый цикл, начинающийся командой с меткой FSTFND, предназначен для определения адреса первого отличного от пробела символа; найденный адрес записывается в регистр 2. Следующий цикл (начинающийся командой с меткой LSTFND) определяет расположение следующего по порядку пробела; соответствующий адрес засылается в регистр 6. Разность (6) — 1 определяет адрес последней цифры числа, это вычитание производится командой с меткой ENDFOUND. После определения знака числа и выполнения связанных с этим операций вычисляется разность (6) — (2) и помещается в регистр 6. Эта разность на единицу меньше количества цифр обрабатываемого числа. Поэтому именно (6) должно быть использовано в качестве содержимого поля длины в машинном формате команды PACK.

Сама команда PACK расположена по адресу PACKER. В машинных кодах эта команда выглядит как

F270C3002000

(регистр 12 использован в качестве базового, значение смещения, соответствующее имени PACDEC, равно 300). Поскольку первый операнд команды должен быть двойным словом, то в качестве его длины в команде языка ассемблера указано 8, содержимое поля длины первого операнда машинной команды соответственно равно 7. Указание 0 или 1 в качестве длины операнда в мнемонической записи команды эквивалентно ссылке на операнд с нулевой длиной, поэтому содержимым полного поля длины PACK является 70. Предположим, что число до упаковки занимало Ю10 байтов. Это значение фактически вычисляется первыми двумя циклами программы рис. 15.9. После выполнения команды SR в регистре 6 окажется

(6) =00000009

В процессе выполнения команды

ЕХ 6,PACKER

содержимое поля длины команды PACK (7016) логически складывается с содержимым последних 8 разрядов регистра 6(091в), при этом получается 791в. Это значение и считается содержимым поля длины команды PACK при ее выполнении, хотя реальное содержимое поля длины команды, находящейся в памяти по адресу PACKER, иное. Другими словами, результат работы команды ЕХ в данном случае такой же, как если бы вместо нее выполнялась команда

PACK PACDEC(8),0(10,2)

В процессе выполнения команды ЕХ содержимое поля длины команды, находящейся в памяти по адресу PACKER, не меняется. Таким образом, если бы следующее число, обрабатываемое программой рис. 15.9, имело длину пять байтов, то выполнение команды ЕХ фактически свелось бы к выполнению команды

PACK PACDEC(8),0(5,2)

Этим мы пока и ограничимся в рассмотрении преобразований, совершаемых над введенной информацией. Несколько позже, в гл. 20, мы познакомимся с командами TR и TRT, также использующимися при проведении такого рода преобразований. Конечно же, если вводимая информация предназначается для обработки командами десятичной арифметики (см. след, главу), то преобразование упакованного десятичного формата в двоичный проводить не надо.

 

В данном случае задача ставится так: в некотором регистре находится двоичное число, необходимо перевести его в десятичную форму и распечатать. При этом неизбежно прохождение всех последовательных этапов преобразования, т. е исходное число будет сначала переведено в упакованное десятичное, затем в зонное десятичное и, наконец, в коды EBCDIC. Коды EBCDIC уже могут быть непосредственно распечатаны.

Пусть, например, в регистре 8 находится вычисленное нами среднее арифметическое некоторой группы чисел. Мы хотим выдать это среднее на печать в форме

AVERAGE = ± ddddddddd

d в данном случае представляет произвольную десятичную цифру. Пока не ставится задача удаления незначащих нулей, этим вы займетесь при выполнении одного из упражнений данной главы.

Программа, выполняющая последовательно все этапы преобразования и производящая вывод требуемого значения, изображена на рис. 15.10. Выводимая строка в данном случае имеет имя OUTPT. Для удобства эта строка разбита на части, имеющие соответствующие их содержанию имена. По команде CVD исходное число, находящееся в регистре 8, переводится в десятичную форму и записывается в двойное слово по адресу PACDEC.

Рис. 15.10. Печать содержимого регистра 8 в виде десятичного числа.

Команда UNPK выполняет дальнейшее преобразование числа в зонный формат и записывает его в область NMBR. Затем производится проверка кода знака, запись соответствующего символа в поле SIGN, и, наконец, код знака заменяется на обычный код зоны F. Получившиеся EBCDIC-коды затем выдаются устройством печати в качестве части строки OUTPT.

 
Статьи раздела