Дополнительные возможности символьной обработки в системе 370

Возможность выполнения команд, к рассмотрению которых мы сейчас перейдем, предусмотрена лишь в машинах Системы 370. При попытке использования их в программе для ЭВМ Системы 360 либо ассемблер отметит употребление неверной мнемоники, либо будет зафиксирован особый случай использования кода операции. Некоторые операционные системы Системы 360 содержат так называемые моделирующие подпрограммы, предназначенные для выполнения команд, действительных лишь для машин Системы 370. Рассмотрение моделирующих подпрограмм выходит за пределы этой книги, необходимые сведения содержатся в руководстве фирмы IBM «System/360 Systems Programmer's Guide».

Команды ICM, STCM, CLM

Одним из недостатков системы команд IBM 360 является то, что при выполнении пересылок или сравнений символьной информации регистры почти не используются. Лучшее, что мы можем сделать, это обеспечить с помощью команды 1C или STC соответственно загрузку или запись в память символьной информации по одному байту. Для сравнения, например, некоторого байта регистра с байтом памяти потребуется предварительная подготовка, включающая загрузку нулей в старшие разряды регистра и помещение в регистры обеих сравниваемых величин. Только после этого, выполнив одну из команд CR или CLR, мы сможем произвести проверку на совпадение интересующих нас байтов. Мы могли поступить и несколько иначе, переписав интересующую нас часть информации с регистра в память и затем выполнить команду CLC с длиной 1. Однако оба способа достаточно утомительны и неэффективны.

С помощью команд ICM, STCM и CLM такие же задачи можно решать значительно проще, поскольку они позволяют загружать в регистры, записывать в память и сравнивать до четырех заранее выбранных байтов сразу.

ICM R1,M3,D2(B2)

Insert Characters under Mask

R1? (D2 + (В2)) в соответствии с М3

STCM R1 ,M3,D2(B2)

Store Characters under Mask

(R1)? D2 + (B2) в соответствии с М3

CLM R1,M3,D2(B2)

Compare Logical under Mask

Вычислить (R1) —(D2+(B2)) в соответствии с М3, установить СС

Все эти команды представляют собой модификацию команд формата RS. Команды обычного формата RS, такие, как, например, STM, требуют указания в качестве операндов двух регистров и одного адреса памяти. В трех описанных выше командах место номера регистра R3 занимает четырехбитовая маска М3.

С помощью этой маски определяются номера байтов регистра, участвующие в операции. Каждый бит М3 соответствует определенному байту R1, бит 0 — байту 0 (первому байту R1), бит 1 —байту 1 и т. д. Если некоторый бит маски равен 1, то это означает, что соответствующий ему байт регистра R1 принимает участие в операции. Маска 6 (=В'0110'), например, говорит о том, что байты 1 и 2, т. е. второй и третий байты регистра R1, записываются в память, сравниваются с содержимым некоторой ячейки памяти или информация из памяти помещается в первый и третий байты регистра R1, в зависимости от выполняющейся операции. Байты, которым в маске соответствуют нулевые биты, участия в операции не принимают.

В качестве операнда, находящегося в памяти, машина берет содержимое последовательных байтов, адрес первого из которых задается адресом D2+(B2), а количество — количеством единиц в маске.

3-байтовому операнду соответствуют маски 1110, 1101, 1011 и 0111. Итак, независимо от маски берется содержимое трех последовательных байтов памяти, начинающихся байтом D2+(B2).

Проиллюстрируем сказанное, рассматривая более подробно команду ICM. Будем считать, что перед началом выполнения команд, соответствующих рассматриваемым ниже примерам, по адресу CHARS записано

С301Е300С1В5

и

(5)=FFFEFDFC

По команде

1СМ 5,В'1 ЮГ,CHARS

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

(5)=C301FDE3

Команда ICM является единственной в группе команд загрузки регистров содержимым некоторых ячеек памяти, устанавливающей значение признака результата в зависимости от перемещаемой информации. Если производится перемещение только нулевых кодов или если в команде указана нулевая маска, то вырабатывается нулевой признак результата. Если первый перемещаемый бит равен 1, что соответствует знаку минус в случае числовой информации, то в качестве значения признака результата вырабатывается 1. Если производится пересылка ненулевой информации, но первый перемещаемый бит, равен нулю, то признак результата получает значение 2, что свидетельствует о пересылке положительного числа.

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

Результат

0

Пересылка 0 или М3 = 0

1

Первый перемещаемый бит=1

2

Первый перемещаемый бит=0, пересылается ненулевая информация

Поскольку в нашем случае первый перемещаемый байт равен СЗ16, то по окончании выполнения команды ICM значением признака результата будет 1.

Заметим, что в результате выполнения команды

ICM 5,l,CHARS+3

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

1C 5.CHARS+3

Отличие будет заключаться лишь в том, что по окончании выполнения первой из них признак результата будет равен 0, а в процессе выполнения второй признак не изменится. Выполнение обеих команд даст

(5) =FFFEFD00. По команде

ICM 5,B'l 11 l', CHARS + 1

производится полная загрузка регистра 5 информацией, содержащейся в четырехбайтовом поле, начинающемся по адресу CHARS+1- Итак, после выполнения этой команды получится

. (5)=01Е300С1

а в качестве значения признака результата будет выработано 2. За исключением установки нового значения признака результата, приведенная выше команда выполняется целиком аналогично команде

L 5.CHARS+1

Команды ICM, STCM и CLM, так же как и все остальные команды обработки символьной информации, не требуют соблюдения при работе с ними правил выравнивания. С помощью команды ICM регистр можно загрузить информацией, располагающейся в любом месте памяти.

В качестве примера использования команды ICM рассмотрим задачу смены значения маски программы, хранящейся в PSW, и установки наперед заданного значения в качестве признака результата. Выполнить поставленную задачу можно с помощью обычного набора команд. Для этого потребуется зарезервировать в памяти полное слово, у которого мы фактически будем использовать лишь первые 8 разрядов. Производится загрузка этого слова в регистр, и выполняется команда SPM:

Статья 428 - Картинка 1

Использование команды ICM позволяет сэкономить память, а также обеспечить сохранность информации в последних трех байтах регистра:

ICM 7,8,MASKBYTE

SPM 7

MASKBYTE DC Х'0З'

С помощью команды STCM определенные байты регистра помещаются в последовательные ячейки памяти, начинающиеся по адресу D2-f-(B2). Значение признака результата при этом не меняется. Пусть, например,

(8)=FFFEFDFC

а по адресу DATA записана следующая информация:

DATA: 00010203040506

При выполнении команды

STCM 8,B'1010',DATA

содержимое первого и третьего байтов регистра 8 будет записано по адресам DATA и DATA+1. В результате получится

DATA: FFFD0203040506

Выполнение команды

STCM 8.1.DATA+2

полностью эквивалентно выполнению команды

STC 8.DATA+2

Записать полное слово в память, не заботясь о соблюдении правил выравнивания, можно, указав в качестве маски команды STCM 15м= =В'111Г. После выполнения команды

STCM 8.15.DATA+1

получится

DATA: 00FFFEFDFC0506

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

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

Результат

0

Операнды равны

1

Операнд 1 < Операнд 2

2

Операнд 1 > Операнд 2

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

(2)=40CDC1E3

и содержимое ячеек памяти, начиная с адреса СОМР, выглядит так: COMP: 40C0D1A30002

По команде

CLM 2, В'1000',СОМР

производится сравнение содержимого первого байта регистра 2 с содержимым байта СОМР. В результате вырабатывается нулевое значение признака результата. В результате выполнения команды

CLM 2,В'1 ЮО'.СОМР

признак результата получит значение 2, поскольку содержимое байтов

0 и 2 регистра 2, а именно 40С1 i6, больше чем 20C0i„, т. е. того, что хранится по адресу СОМР.

Пересылка длинная

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

MVCL R1,R2

MoVeCharacter Long

См. табл. 20.1

R1 и R2 должны в данном случае указывать четные регистры. Содержимое регистров Rl, Rl + 1, R2 и R2+1 используется для определения следующих значений:

(R1)8-31 = Адрес назначения = DA

(R2)8-31 = Исходный адрес = SA

(R1 + 1)8-31 = Длина области назначения = DL

(R2+1)8-31 = Исходная длина = SL

(R2 + l)0-7 =Символ-заполнитель = Р

Мы будем пользоваться введенными сокращениями в процессе рассмотрения команды MVCL. Например, с помощью SL мы будем обозначать содержимое разрядов 8—31 регистра R2+1.

Основная функция команды MVCL заключается в пересылке данных, хранящихся по адресу SA, в область памяти, начало которой имеет адрес DA. С помощью DL и SL определяется количество пересылаемой информации и необходимость заполнения оставшейся незанятой после пересылки части области, в которую эта пересылка производится, символом-заполнителем Р. Вообще говоря, исходная длина совсем не обязана совпадать с длиной области назначения. На самом деле существует три различных способа выполнения команды MVCL, которые применяются в зависимости от того, в каком соотношении находятся длина области назначения и исходная длина. Исходная длина может равняться длине области назначения, быть больше ее или меньше. Поскольку для указания длины в данном случае отведено 24 разряда, то, следовательно, наибольшей длиной может являться 16777215.

SL—DL. В случае корда длина области назначения совпадает с исходной длиной, команда MVCL выполняется почти аналогично команде MVC. Разница заключается лишь в том, что не существует ограничения на количество перемещаемой информации. При выполнении команды MVCL производится пересылка содержимого SL последовательных байтов, начиная с байта SA, в такую же по размерам область памяти, начинающуюся по адресу DA. Однако в отличие от МУС при выполнении MVCL изменяется содержимое регистров и устанавливается новое значение признака результата. По окончании выполнения пересылки содержимое регистров изменяется на следующее:

(R1)8-31 = SA + SL = адрес первого по порядку байта,

не принадлежащего исходной области

(R1 + 1)8-31 = 0

(R2)8-31 = DA + DL = адрес первого по порядку байта,

не принадлежащего области назначения

(R2 + l)8-31 = 0

Другими словами, при выполнении пересылки содержимое полей длины уменьшается, а содержимое полей адресов увеличивается каждый раз при перемещении одного байта на 1. Окончательно в полях длины получаются нули, что свидетельствует о том, что пересылка закончена, а поля адресов, естественно, содержат адреса первых по порядку не входящих в соответствующие области байтов. Если SL=DL, то по окончании выполнения команды MVCL в качестве признака результата вырабатывается 0.

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

(4) =00040000=DA

(5) =00002000=D L

(8) =00035000=SA

(9) =00002000=SL

Команда

MVCL 4,8

выполнит необходимую пересылку. Содержимое регистров в результате будет таким:

(4) = 00042000 = DA + DL

(5) = 00000000

(8) = 00037000 = SA + SL

(9) = 00000000

Признак результата получит значение 0.

DL>SL. Если исходная длина меньше длины области назначения, то это фактически означает, что перемещаемая информация занимает меньше места, чем то, которое под нее отводится. В этом случае SL байтов исходной области записываются, начиная с первого байта области назначения, а остальная часть этой области заполняется кодами символа-заполнителя Р. В качестве особого можно выделить случай, когда SL=0. При этом кодом Р заполняется вся DL-байтовая область, начинающаяся по адресу DA.

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

(R)8-31 = DA + DL

(R1+1)8-31= 0

(R2)8-31 = SA+SL

(R2 + l)8-31 = 0

В качестве признака результата вырабатывается 2, что соответствует тому, что первоначально (R1 + 1)8-31>(R2+1)8-31.

На рис. 20.1 приведен пример использования команды MVCL для формирования строки, предназначенной для вывода с помощью устройства печати. Команды LA осуществляют загрузку регистров значениями исходной длины и длины области назначения, а также соответствующими адресами. По команде LCMв разряды 0—7 регистра 11 записывается код символа-заполнителя.

Статья 428 - Картинка 2

Рис. 20.1. Пересылка 10 байтов из поля MESS в первые 10 байтов поля LINE и заполнение остальной части поля пробелами.

По окончании выполнения команды MVCL имеем:

(6)8-31= A(LINE) + 13210

(7)8-31= 00000000

(10) = A(MESS) + 1010

(11) = 00000000

иСС=2.

DLC5L. В данном случае область назначения слишком мала для записи в нее всей информации, хранящейся в исходной области. Происходит пересылка содержимого первых DL байтов области SA в область, начинающуюся по адресу DA. Содержимое регистров при этом изменяется таким образом, что следующая команда MVCL, использующая эти же регистры, начнет выполняться, начиная с того места, на котором закончилось выполнение предыдущей. Иными словами, значение SL уменьшается, a SA увеличивается на DL, количество перемещенных байтов. По окончании выполнения

(R1)8-31 = DA+DL

(R1 + 1)8-31 = 0

(R2)8-31 = SA+ DL

(R2 + 1)8-31 = SL— DL

и СС= 1.

Такая организация работы MVCL оказывается очень удобной в случае, когда необходимо последовательно производить перемещения отдельных частей некоторой совокупности данных. Аналогичная работа выполняется операционной системой при организации ввода отдельных записей, входящих в блоки, получаемые от устройств ввода. Предположим, например, что размер блока равен 4000 байтам, а программа запросила ввод по 1000 байтов по одному запросу. Система осуществляет ввод блока и записывает его адрес и число 1000 в регистры в качестве исходного адреса и длины области назначения. Вызывающая программа записывает в соответствующий регистр адрес области назначения.

Статья 428 - Картинка 3

Рис. 20.2. Схема подпрограммы, передающей исходную информацию вызывающей программе порциями по 1000 байтов.

В началеисходная длина равняется 4000. По первому запросу вызывающей программы производится перемещение первых 1000 байтов блока по адресу назначения. Получившиеся в результате новые значения исходной длины и исходного адреса используются для выполнения пересылки при обслуживании следующего запроса. На рис. 20.2 приведена общая структура подпрограммы, предназначенной для выполнения такого рода операций.

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

При выборе какой-либо из двух команд, MVC или MVCL, для использования в конкретной ситуации необходимо учитывать следующие соображения.Использование команды MVCL позволяет несколько упростить программную логику и уменьшить количество обращений к памяти, необходимых для пересылки значительных объемов информации. Однако, с другой стороны, это влечет за собой потерю некоторого количества времени на загрузку четырех активно использующихся командой MVCL регистров соответствующими значениями. Загрузка регистров в свою очередь может вести к новым, теперь уже неявным потерям. Дело в том, что если в регистрах находится некоторая ценная информация, то нужно организовывать сохранение содержимого регистров, а также последующее восстановление.

Таблица 20.1 Сводная информация по команде MVCL

Команда: MVCL R1,R2

R1, R2 должны иметь четные номера

Первоначальное содержимое регистров:

(R1)8-31 = адрес области назначения DA

(R1 + 1)8-31 = длина области назначения DL

(R2)8-31 = адрес исходной области SA

(R2+ 1)8-31 = длина исходной области SL

(R2+1)0-7 =символ-заполнитель Р

Окончательное содержимое регистров:

(R1)8-31 =DA+ DL

(R1 +1)8-31 = 0

(R2)8-31= SA + min [DL, SL]

(R2+1)8-31 = max[SL-DL, 0]

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

Значение

Результат

0

DL = SL

1

DL < SL

2

DL > SL

3

Перекрытие полей; пересылка не производится

Пересылаемые данные:

DL = SL: SL байтов из DA в SA

DL<SL: DL байтов из DA в SA

DL >SL: SL байтов из DA в SA;

оставшаяся часть области назначения замещается символом-заполнителем.

Рассмотрев пример, приведенный на рис. 20.1, вы могли совершенно справедливо заметить, что использование MVCL в данном случае себя не оправдывает, гораздо лучше можно было сделать то же самое, используя команды МУС и MVI. Мы выбрали данный пример именно для того, чтобы сконцентрировать ваше внимание на только что рассмотренных вопросах.

20.1.3. СРАВНЕНИЕ КОДОВ ДЛИННОЕ

Операнды команды CLCL имеют тот же вид и почти тот же смысл, что и операнды команды MVCL.

CLCL R1,R2

Compare Logical Character Long

См. табл. 20.2

(R1)8-31 = Адрес первого операнда = FA

(R1 + 1)8-31 = Длина первого операнда = FL

(R2)8-31 = Адрес второго операнда =SA

(R2 + 1)8-31 = Длина второго oпepaнда = SL

(R2+1)0-7 = Символ-заполнитель = Р

При выполнении команды CLCL происходит побайтовое сравнение содержимого двух областей памяти, пока области не будут исчерпаны,

Таблица 20.2

Сводная информация по команде CLCL

Команда: CLCL R1,R2

R1, R2 должны иметь четные номера

Первоначальное содержимое регистров:

(R1)8-31 = адрес первого операнда FA

(R1 + 1) 8-31= длина первого операнда FL

(R2)8-31 = адрес второго операнда SA

(R2+ 1)8-31 = длина второго операнда SL

(R2+1)0-7 = символ-заполнитель Р

Содержимое регистров, после того как результатом сравнения первых М байтов оказалось равенство:

(R1 )8-31 = FA + M

(R1 +l)8-31 = max [0, FL—M]

(R2)8-31 = SA -f- M

(R2+ l)8-31 = max [0, SL—M]

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

Значение

Результат

0

первый операнд = второй операнд

1

первый операнд < второй операнд

2

первый операнд > второй операнд

если их содержимое совпадает, или пока не будет найдена неравная пара байтов. В зависимости от результата сравнения устанавливается новое значение признака результата.

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

Результат

0

Операнд 1=Операнд 2

1

Операнд 1 < Операнд 2

2

Операнд 1 > Операнд 2

Если значения, указанные в полях длин операндов регистров R1 + 1 и R2+1, не совпадают, то при сравнении считается, что содержимое более короткой области дополнено необходимым количеством символов-заполнителей.

Если при сравнении было зафиксировано равенство, то содержимое регистров по окончании выполнения команды CLCL выглядит так:

(R1)8-31 = FA + FL

(R1+1)8-31=0

(R2)8-31 = SA + SL

(R2 + 1)8-31 = 0

При этом CC=0.

Если операнды не равны, то предположим, что первые их М байтов совпали. В этом случае содержимое регистров по окончании выполнения команды CLCL будет таким:

(R1)8-31 = FA + M

(R1 + 1)8-31 = большее изО, FL—М

(R2)8-31 = SA + M

(R2 +1)8-31 = большее изО, SL—М

В качестве значения признака результата при этом вырабатывается1 или 2 в зависимости от того, меньше первый операнд, чем второй, или больше.

Другими словами, если содержимое рассматриваемых областей не совпадает, то CLCL останавливается на первой паре не совпавших байтов и признак результата вырабатывается в зависимости от соотношения между содержимым этих байтов. В адресных частях регистров находятся адреса первых не совпавших байтов, содержимое полей длины показывает, сколько байтов осталось сравнить.

Для иллюстрации возможностей использования команды CLCL рассмотрим несколько примеров. Эти примеры будут несколько неестественны с той точки зрения, что на практике команда CLCL используется для сравнения содержимого гораздо больших областей, чем те, которые рассматриваются в примерах. Тем не менее, основные принципы работы остаются теми же самыми. Предположим, что содержимое областей ОР1 и ОР2 выглядит так:

OP 1: 404040СЗС1Е3404040404040

ОР2: 404040СЗС1D9404040404040

Для сравнения содержимого областей необходимо написать

LA 6,ОР1

LA 7,12

LA 10,ОР2

LR 11,7

CLCL 6,10

Содержимое ОР1 больше содержимого ОР2, различие начинается с шестого байта. Таким образом, по окончании выполнения CLCL будем иметь

(6) = А(ОР1) + 5

(7) = 00000007 (Ю) = А(ОР2) + 5 (11) = 00000007

и

СС=2

Теперь предположим, что мы имеем следующую последовательность команд:

LA 6,ОР1

LA 7,4

LA 10,ОР2

LA 11,12

ICM 11,8, = Х'40'

CLCL 6,10

Так как длина первого операнда в данном случае меньше длины второго, то в качестве содержимого ОР1 будет принято

404040С34040404040404040

Это будет происходить потому, что. вследствие разницы в длинах операндов оставшаяся часть первой области считается заполненной кодами символа-заполнителя. В результате выполнения приведенной последовательности команд получится

(6) = А(ОР1) + 4

(7) = 00000000 (Ю) = А(ОР2) + 4

(11) = 40000008

и

СС=1

Несовпадение содержимого областей началось с пятого байта. 40 меньше, чем С1, и поэтому признак результата получил значение 1.