Команда ZAP. Пересылка десятичной информации - Команды MVZ, MVN и MVO

ЭВМ Системы 369 не содержит команд десятичного сдвига как таковых. Желаемые результаты могут быть получены достаточно сложным образом, для этого потребуется использование логических команд и команд пересылки. Например, по команде

MVC NUM — 2(5), NUM

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

NC NUM + 2(3), = X'F0000F'

Таким образом, если исходное содержимое области памяти, начинающейся по адресу NUM—2, выглядело как

NIJM—2: FECB038602795C

то после выполнения указанных команд получится

0386027950000С

Итак, пара команд MVC и NC может быть использована для получения произведения произвольного числа на любую четную степень 10 или для сдвига десятичной информации влево на любое целое число байтов. Но как быть, если требуется что-либо умножить на нечетную степень числа 10? Ведь выполнение подобного действия включает сдвиг содержимого памяти на 4 бита. Как, кроме того, можно использовать сдвиги для выполнения деления десятичных чисел?

ЭВМ Системы 360 не предусматривают непосредственных ответов на поставленные вопросы. В подобных случаях могут быть использованы команды MVZ, MVN и MVO, однако применение команд МР и DP позволяет обычно получить те же результаты более эффективно и, главное, более просто. Все же, как мы увидим в дальнейшем, команды MVZ, MVN и MVO в некоторых случаях могут оказаться весьма полезными.

ЭВМ Системы 370 реализуют специальную команду десятичной арифметики SRP (СДВИГ С ОКРУГЛЕНИЕМ ДЕСЯТИЧНЫЙ), которая является настоящей командой десятичного сдвига. Поскольку возможностью выполнения команд MVZ (ПЕРЕСЫЛКА ЗОН), MVN (ПЕРЕСЫЛКА ЦИФР) и MVO (ПЕРЕСЫЛКА СО СДВИ¬ГОМ) обладают, все ЭВМ Системы 370, то мы сначала рассмотрим их, а затем перейдем к рассмотрению команды SRP и определяемых ею дополнительных возможностей.

 

MVZ D1(L,B1),D2(B2)

MoVe Zones

Зонные части (D1+(B1))? зонные части (D2 + (B2))L

MVN D1(L,B1),D2(B2)

MoVe Numeric

Цифровые части (D1 + (В 1))? цифровые части (D2+(B2))L

MVO D1(L,B1),D2(B2)

MoVe with Offset

См. текст

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

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

Пусть

Р1: 12345678

Р2: ABCDEABC

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

MVZ Р1(4),Р2

даст следующий результат:

Зонные части Р2 записаны в Р1 вместо его зонных частей. Аналогично по команде

MVN Р1(4),Р2

производится замещение вторых половин всех байтов поля Р1 вторыми половинами соответствующих байтов поля Р2:

Р2: ABCDEABC

PI: 1B3D5A7C

Так же как и в случае команды MVC, если операнды перекрываются, то для получения представления о результате можно считать, что процесс пересылки является побайтовым, причем байты второго операнда рассматриваются последовательно, слева направо. Например, по команде

MVZ Р1 + 1(3),Р1

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

По команде

MVN Р2(2),Р2+2

цифровые части двух последних байтов Р2 будут сдвинуты на 2 байта влево:

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

NUM: 3456789С

Перемещение знакового кода С на 2 байта влево равносильно делению числа на 10000. Если выполнить сдвиг, то в ячейке NUM получим

NUM: 345С789С

такой сдвиг можно осуществить с помощью команды

MVN NUM+l(l),NUM+3

Отметим, что в результате выполнения команды DP мы получили бы другой ответ. Это объясняется тем, что в данном случае мы не позаботились о вычислении остатка. Полученное нами число является двухбайтовым, и поэтому при последующем использовании его в качестве операнда команд десятичной арифметики на месте длины следует указывать 2.

Команда MVZ бывает очень полезна при выполнении различного рода преобразований данных. Например, при переводе числа из кода EBCDIC в зонный десятичный формат необходимо, в частности, поместить внутрь числа соответствующий код знака. Если код знака должен быть помещен по адресу INPT+3, то пара команд

OI INPT 4-3,X'F0'

N1 INPT +3,X'DF'

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

MVZ INPT+3(l),MZONE

при условии, что наша программа содержит предложение

MZONE DC X'DO'

Рис. 16.1. Команда MVO. Сплошные вертикальные линии обозначают границы байтов, пунктирные — полубайтов. До начала выполнения G содержит FFFFFD.

С очень похожей задачей нам приходится встречаться при проведении обратных преобразований, т. е. преобразований из зонного формата в коды EBCDIC. Вы помните, что для этого, в частности, нужно поместить код F в знаковую зону, чтобы представить последнюю цифру числа в коде EBCDIC. Пусть 6-байтовое зонное десятичное число записано в памяти по адресу OUTPT. Описанного эффекта можно добиться, выполнив команду

MVZ OUTPT+5(l), = X'FO'

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

Пересылка производится по одному байту, при этом порядок рассмотрения байтов второго операнда последовательный, справа налево. Фактически, команда MVO выполняется так же, как и MVC. Отличия заключаются только в «косой» пересылке (рис. 16.1), или пересылке со сдвигом, возможности дополнения незначащих нулей и отсутствии фиксации переполнения.

На рис. 16.1 приведена общая схема выполнения команды MVO. Здесь же приведен конкретный пример. Еще несколько примеров, вероятно, окончательно прояснят для вас назначение и способ выполнения команды MVO. Пусть . ;

NUMS: 123456789С

ANS: АААААААА

Ниже приведены выполняемые команды и соответствующие результаты:

MVO ANS(2),NUMS(1)

ANS: 012ААААА

MVO ANS(3),NUMS(1)

ANS: 00012AA A

MVO ANS(3),NUMS(2)

ANS: 01234AAA

MVO ANS(2),NUMS(5)

ANS: 89CAAAAA

Рассмотрим еще один пример. Предположим, что по адресу Q записано 4-байтовое десятичное число:

Q: 6742198С

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

PROD: FFFFFFFFFFFFFFFF

Выполним сначала «косую» пересылку содержимого Q в область PROD.

Эту пересылку нужно осуществить таким образом, чтобы в конце PROD осталось два свободных байта (место для записи трех цифр и кода знака). Можно также сразу заполнить левую свободную часть PROD нулями. Для выполнения этих действий используем команду MVO:

MVO PROD(7),Q(4)

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

PROD: 000006742198CFFF

Теперь код знака из поля Q помещаем в соответствующее место поля PROD:

MVN PROD+7(l),Q+3

После выполнения этой команды содержимое области PROD будет иметь следующий вид:

000006742198CFFC

Заменяем три последние цифры нулями:

NC PROD+6(2),=X'OOOF'

Окончательно будем иметь

PROD: 000006742198000С

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