Диапазон проверки сравнения CL не работает - PullRequest
0 голосов
/ 24 января 2019

Я проверяю некоторые входные данные; число ввода должно быть от 1 до 255. И я пытаюсь следующий код. Вход определен, вход DC CL60 '' '

clc   input,=c'255'   
bh    loop1
clc   input,=c'1'     
bl    loop1
J     loop2 
loop1

Вышеупомянутая проверка работает только для трехзначных чисел (от 100 до 255) Но это не работает для двузначного числа. Не могли бы вы помочь мне :)

Ответы [ 2 ]

0 голосов
/ 29 января 2019

Многое зависит от того, насколько гибким вам должно быть ваше поле «ВХОД». Например, если вам нужно обрабатывать C'1 ', C' 1 ', C' 1 ', C'01', C '01' и C'001 'одним и тем же способом, то вам нужно выполнить дополнительную работу ,

У вас есть два варианта в целом. Либо вы можете «нормализовать» ваши данные в трехсимвольное поле (другими словами, приведите все примеры, которые я упомянул выше C'001 '), либо вы можете выполнить какое-то воображаемое сравнение переменной длины, чтобы приспособиться к размеру значений, которые вы' пытаюсь сравнить.

Это будет иметь для вас больше смысла, если вы немного углубитесь в работу CLC. Если вы посмотрите на список ассемблера вашей программы, вы увидите код объекта для CLC, который вы закодировали в шестнадцатеричном формате ... это будет что-то вроде D5llsaaatbbb где:

  • "D5" - это код операции - CLC
  • "ll" - длина сравнения, которое вы делаете
  • "s" - это первый регистр базы операндов
  • "ааа" - это первое смещение операнда
  • "t" - регистр базы второго операнда
  • "bbb" - смещение второго операнда

Так что, если ваше поле ввода действительно DC CL60 '', и оно хранится на 100 байтов от регистра 10, а литерал (= C'whwh ') составляет 40 байтов от регистра 12, вы увидите D53BA064C028. Код достаточно ассемблер, и вы будете читать эти вещи, как будто они были на английском языке. :)

Как указывает один из других авторов, ассемблер устанавливает длину по умолчанию равной длине первого операнда, поэтому сразу же возникает проблема, поскольку вы выполняете сравнение (ввод clc, = C'1 ') заставляет ассемблер генерировать 60-байтовое сравнение, даже если второй операнд имеет длину только один байт. Если вы хотите сделать это таким образом, вам нужно кодировать его как ввод clc, = CL60'1 ... '. Вот почему обычно удобнее либо кодировать инструкцию «назад» (как в clc = C'1 ', input), либо явно указывать длину (как в clc input (1), = C'1'), чтобы вы не пройдите мимо конца поля, с которым вы сравниваете.

Следующая проблема, с которой вы столкнетесь, - это сравнение переменной переменной длины. Много раз вы захотите выяснить, сколько у вас цифр, а затем сравнить это количество цифр, а не длину поля. Например, вы можете посмотреть на данные, закодированные как «1», и решить пропустить пропуски и просто проверить поле как однобайтовое значение. Для такого рода вещей команда execute (EX) - ваш друг - она ​​дает вам простой способ сравнения переменной длины.

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

* Assume you have the length in R1
       BCTR R1,0         Don't forget lengths are 0-relative (00 = 1 byte, FF=256)
       EX   R1,MYCLC     Do the comparison using the length in R1
       J    *+10         Skip over the CLC instruction
MYCLC  CLC  INPUT(0),PATTERN       Executed instruction

Инструкция EX использует первый операнд для обновления целевой команды, а затем выполняет ее. В этом примере EX использует значение в R1, чтобы установить длину в CLC, что дает вам сравнение переменной длины. Обратите внимание на длину 0 - в этом случае объектный код будет D500, EX "ИЛИ" младшие биты R1 с 00, чтобы дать вам желаемую длину. Просто, правда?

Последний фрагмент головоломки - это анализ вашего поля INPUT, при условии, что это поле свободной формы, которое может содержать такие вещи, как пробелы. Обычная потребность в этом - найти начальное непустое поле в более длинной строке ... здесь, переводчик и тест (TRT) - ваш друг. Я не буду утомлять вас деталями, но он дает вам одну инструкцию, которая может сканировать поле, чтобы найти какой-либо конкретный символ - например, непустой или пустой. Пара инструкций TRT может помочь вам найти начало и конец любой строки с разделителями, аналогично strchr () в C (если вы программист на C). Небольшое вычитание, чтобы получить некоторую длину, и вы готовы сделать то, что вам нужно, с помощью сравнения переменной длины, описанного выше.

По мере того, как вы будете писать больше ассемблера, вы поймете все маленькие хитрости, которые облегчают эти задачи. Например, «особенностью» EBCDIC является то, что шестнадцатеричное кодирование цифр находится в верхней части шкалы: от F0 до F9. Это означает, что во многих простых приложениях вам на самом деле не приходится иметь дело с вашим случаем «выше, чем 999», потому что все буквенные и типичные символы ниже, чем C'0 '... просто проверка на не менее чем 0 обычно достаточно для символьных данных.

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

0 голосов
/ 25 января 2019

Когда ассемблер генерирует длину для сравнения, он основан на первом операнде.Вы не показываете это в коде, но я предполагаю, что это что-то вроде

INPUT DS CL3

В этом случае инструкция CLC input,=c'1' сравнивает трехбайтовое поле с литералом в 1 символ,Итак, вы сравниваете трехбайтовую область с трехбайтовой областью, которая представляет собой значение в 1 символ, поэтому вторые два байта не определены.

Если вы хотите основать сравнение на основе литерала, вы можете сделать это вместо этого:

         clc   =c'255',input   
         bh    loop1
         clc   =c'1',input     
         bl    loop1
         J     loop2 
loop1

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

Например, предположим, что это ваш код:

             PACK DecimalInput,Input  
             CP   DecimalInput,=P'255'  
             BH   TooHigh  
             CP   DecimalInput,=P'1'  
             BL   TooLow
JustRight    DS  0H


DecimalInput DS   PL3 
Input        DS   CL3  

Конечно, вам нужно будет проверитьэто числа, или вы получите S0C7.

...