Команды редактирования

Помните ли вы, насколько неприятным был процесс перевода упакованных десятичных чисел в коды EBCDIC, описанный в гл. 15? Команды ОТРЕДАКТИРОВАТЬ и ОТРЕДАКТИРОВАТЬ И ОТМЕТИТЬ позволяют вместо непосредственной организации этого процесса воспользоваться услугами ЭВМ.

Команда ОТРЕДАКТИРОВАТЬ (EDit — ED) представляет собой некоторый усложненный вариант команды UNPK.

ED D1 (L1 ,B1),D2(B2)

EDit

Преобразование (D2+(B2))

в коды EBCDIC, используя образец (D1+(B1)), и размещение по адресу D1+(B1)

Для работы с этой командой в область, в которой предполагается получить коды EBCDIC, необходимо поместить так называемый образец, или шаблон. Образец — это строка, состоящая из некоторых специальных кодов и символов. Коды определяют порядок выполнения редактирования. Отметим три из них:

Код Название

20 Выбор цифры

21 Начало значимости

22 Разделение полей

Первый символ образца называется символом-заполнителем. Кодом символа-заполнителя замещаются все незначащие нули, полученные в результате распаковки числа.

По команде ED распаковка производится последовательно, начиная с левого конца второго операнда. Для распаковки каждой 4-битовой цифры к ней спереди приписывается Fie. В машине существует переключатель, служащий для хранения информации о значении так называемого указателя значимости. В момент начала выполнения команды ED указатель значимости равен 0 (переключатель находится в состоянии выключено), и таким он и остается до тех пор, пока либо не будет найдена ненулевая цифра во втором операнде, либо мы не встретим символ начала значимости в образце. До тех пор пока указатель значимости равен 0, старшие нули второго операнда заменяются кодом символа-заполнителя. После того как значение указателя значимости станет равным 1, все цифры, даже нули, будут распаковываться и записываться в память по общему правилу. Таким образом, при выполнении команды ED старшие незначащие нули заменяются кодами символа-заполнителя, в качестве которого обычно выступает пробел.

Образец по длине совпадает с конечной строкой кодов EBCDIC. Эта длина задается в поле L1 команды. В простейшем случае может требоваться распаковать исходное число и заменить старшие нули пробелами. Если исходное число занимало 3 байта, то нам нужно место для записи пяти цифр. В этом случае мы используем образец

PATTRN: 4020202020

Заметим, что коды выбора цифры используются, по существу, для указания мест, на которые впоследствии будут помещены соответствующие цифры. Предположим, что по адресу PACDEC находится упакованное десятичное число, которое требуется распаковать. Мы используем команду

ED PATTRN(5), PACDEC

Если содержимое области PACDEC в начале имело вид 00036С, то по окончании выполнения команды редактирования получится

PATTRN: 404040F3F6

что соответствует строке b53.49. Заметим, что при выполнении команды ED половины последнего байта не меняются местами. В данном случае все комбинации F0, полученные в результате распаковки старших нулей, заменяются пробелами, поскольку при их обработке указатель значимости равен 0. При обработке четвертой цифры, а именно цифры 3, значение указателя меняется, и поэтому в четвертый байт области PATTRN записывается F3. По этой же причине в последний байт записывается F6.

Все обычные символы, включенные в состав образца вслед за символом-заполнителем, в процессе преобразований не изменяются, если на момент их обработки признак значимости равен 1, и, следовательно, входят в получающуюся строку кодов EBCDIC. Предположим, что опять требуется распечатать пятизначное число, но теперь перед двумя последними цифрами необходимо поместить десятичную точку. Для этого достаточно включить код «.», имеющий значение 4В10, в образец. В данном случае образец будет иметь следующий вид:

PATTRN: 4020204В2020

Если теперь в памяти по адресу PACDEC находится строка 05349D, то после выполнения команды

ED PATTRN(6), PACDEC

получится

PATTRN: 40F5F34BF4F9

что соответствует выдаваемой на печать строке

b53.49

т.е. тому, что мы и хотели получить.

Однако при редактировании числа, подобного 00002С, с помощью рассмотренного образца мы неизбежно получим неправильный результат. Поскольку указатель значимости равен 0 до начала обработки последней цифры, то, следовательно, единственной цифрой, которая получится в результате редактирования, будет 2. То есть по окончании выполнения команды ED мы будем иметь

PATTRN: 4040404040F2

И именно здесь следует воспользоваться возможностями специального кода начала значимости. При встрече в образце кода 21 значение указателя значимости независимо от обрабатываемой в настоящий момент цифры меняется на 1. Оставшиеся цифры второго операнда будут распаковываться уже при условии, что признак значимости равен 1. Итак, если мы используем строку

4020214В2020

в качестве образца, то как десятичная точка, так и две последние цифры будут, безусловно, распаковываться и распечатываться. Если по адресу PACDEC находится число 00002С, то после выполнения команды ED с указанным образцом получится

4040404BF0F2

что соответствует

bbb.02

Если вместо указанного использовать образец

4021204В2020

то в результате получится

4040F04BF0F2

что соответствует

bbb0.02

Код разделения полей служит для сброса признака значимости в 0. В результирующей строке он всегда заменяется символом-заполнителем. С помощью разделителя полей можно редактировать многозначные числа и помещать результат в несколько более коротких полей.

Однако у нас еще не шла речь о знаке редактируемого числа. При выполнении команды ED устанавливаются следующие значения признака результата:

Признакрезультата

Результат

0

Распакованное числоравно 0

1

Распакованное числоменьше 0

2

Распакованное числобольше 0

Если мы используем разделитель полей, то признак результата устанавливается в соответствии с содержимым последнего распакованного поля.

Наше последнее замечание касается того, что при выполнении команды ED использующийся образец разрушается. Обычно мы храним дубликат образца и при необходимости помещаем его в область, в которой хотим получить очередное распакованное число. Для получения шестизначного распакованного числа по адресу OUTNUM в предположении, что содержимое памяти то же, что и в предыдущем примере, мы напишем

MVC OUTNUM(6), PATTRN

ED OUTNUM(6), PACDEC

PATTRN DC X'4021204B2020'

Отредактировать и отметить

Команда ОТРЕДАКТИРОВАТЬ И ОТМЕТИТЬ (EDit and МагК — EDMK) почти ничем не отличается от команды ED. Единственное незначительное различие заключается в том, что при выполнении команды EDMK в регистр 1 помещается адрес байта, при обработке которого меняется указатель значимости. Это оказывается удобным в случаях, когда непосредственно перед первой значащей цифрой требуется напечатать определенный символ.

EDMK D1(L1,B1),D2(L2)

EDitand МаrК

Преобразование (D2+(B2)) в коды EBCDIC, используя (D1+(B1)), и размещение по адресу D1 +(В1)

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

хх,ххх.хх

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

РАТТ: 40206В2021204В2020

Если исходное упакованное число находится по адресу PAYPAC, а результат (строку кодов EBCDIC) мы хотим получить по адресу PAY, то задача будет выполнена, если мы напишем следующую последовательность команд:

MVCPAY(10),PATT

EDMK PAY(IO),PAYPAC

BCTR 1,0

MVI 0(1),C'$'