Предварительные сведения — Работа с регистрами
ТИПЫ КОМАНД
Мы видели, что команда машинного языка состоит из двух частей, поля операции и поля операндов. В Системе 360 существует по крайней мере три различных типа операндов. Операнд может находиться в регистре общего назначения, храниться в памяти, его значение также может быть указано в самой команде. Операнды последнего типа называются непосредственными операндами. В пяти типах команд встречаются различные комбинации операндов различных типов. Каждый тип команд языка ассемблера соответствует определенному формату машинного языка. Тип команды определяется типом ее операндов. Существуют следующие типы команд (в скобках указаны стандартные сокращения их названий):
Регистр-Регистр (RR): оба операнда хранятся в регистрах общего назначения.
Регистр-Индексированная Память (RX): первый операнд — в регистре общего назначения, второй — в ячейке памяти, которая может быть указана с использованием индекс-регистра.
Регистр-Память (RS): первые два операнда в регистрах, третий— в основной памяти.
Память-Память (SS): оба операнда находятся в основной памяти. Память-Непосредственный операнд (SI): первый операнд в памяти, второй задан в самой команде.
Функции команд
Рассмотренное разделение команд по типам чисто механическое, тип команды зависит исключительно от типов операндов и нужен для правильного написания соответствующей команды и правильного задания операндов. Можно классифицировать команды в соответствии с действиями, которые по ним выполняются, т. е. в соответствии с функциями команд. Таким способом можно разделить все существующие команды на пять основных категорий.
Команды пересылки: по командам этого типа производится пересылка информации из одной области памяти в другую. Например, команда MVCслужит для пересылки содержимого областей памяти по новому адресу, а команда LRпересылает содержимое одного регистра в другой регистр.
Арифметические команды: именно эти команды действительно преобразуют информацию. К этому типу относятся такие операции, как «сложить», «умножить», логические операции «и», «или» и некоторые другие команды, изменяющие форму хранимой информации.Команды сравнения: часто требуется сравнить поля информации без нарушения их содержимого. Мы, например, можем установить, больше ли содержимой регистра 3 содержимого регистра 10, с помощью команды сравнения формата RR.
Команды перехода: эти команды используются для изменения обычного порядка выполнения команд в программе. Существуют команды условного и безусловного перехода. Например, можно использовать команду условного перехода для выбора следующей команды из некоторой заданной ячейки, если результат выполнения предшествующей команды сложения окажется отрицательным.
Команды ввода-вывода: эти команды осуществляют управление работой периферийных устройств и соответствующими потоками информации.
Тип и функция позволяют определить группу, из которой следует выбирать команду, наиболее подходящую для выполнения заданных действий. Размещение операндов в памяти и их тип определяют тип команды; выполняемое по данной команде действие характеризует функцию команды. Во многих случаях эта классификация позволяет программисту однозначно выбрать необходимую команду. Иногда требуется дальнейший выбор, например выбор соответствующей арифметической команды. В любом случае описанная классификация достаточно полезна программисту, пишущему на языке ассемблера.
В нескольких последующих главах будет рассмотрен каждый тип команд в отдельности. Будут показаны типичные примеры применения команд каждого типа и подробно рассмотрены их эквиваленты на машинном языке. По окончании рассмотрения всех пяти типов команд мы будем готовы к применению основных изученных принципов в некоторых специальных случаях программирования на языке ассемблера.
Символическое представление команд
Всюду в дальнейшем мы будем пользоваться символической формой рассматриваемой команды. При этом мы будем демонстрировать возможности записи команд в этой символической форме по мере необходимости. Пока заключим следующее соглашение: все операнды, находящиеся в регистрах, мы будем обозначать с помощью буквы Rс последующим указанием номера соответствующего операнда. Так, например, R2 может означать операнд, находящийся в любом из 16 регистров общего назначения, причем этот операнд является вторым операндом данной команды. Содержимое данного регистра обозначается заключением его адреса в круглые скобки. Поэтому (5) обозначает либо содержимое ячейки памяти с номером 5, либо содержимое регистра 5. В каждом конкретном случае будет ясно, что представляет собой адрес, заключенный в скобки.
Мы будем также использовать стрелку () для обозначения операции запоминания результата в регистре или в ячейке памяти. Используя все эти соглашения, можно символически записать результат выполнения команды ARкак
что можно выразить словами так: «Содержимое регистра, указанного первым, сложено с содержимым регистра, указанного вторым, и результат помещен в первый регистр». Конец стрелки направлен влево, так как в большинстве случаев это отвечает реальному направлению перемещения информации. Результат выполнения операции обычно запоминается в регистре или ячейке памяти, заданных в качестве первого операнда, т. е. указанных первыми в поле операндов команды.
Особые случаи в программе
Обычно нас интересует, что происходит, если команда написана и выполняется правильно. Однако случается и так, что вследствие нашей ошибки производится попытка выполнения команды, которое невозможно завершить или которое по завершении дает бессмысленные результаты. Мы уже видели, что попытка сложить два слишком больших числа может привести к ситуации, называемой переполнением; в результате обычно получается число, которое никак нельзя рассматривать как сумму двух исходных чисел.
Ошибки, приводящие к попыткам выполнения того, для чего ЭВМ не предназначена, называются особыми случаями в программе. Они обычно приводят к прерыванию выполнения нашей программы и выдаче некоторой информации, по которой можно судить о причине прерывания. Сообщение выдается в форме, которая будет рассмотрена в гл. 12; пока мы будем просто отмечать возможность возникновения таких ситуаций.
Логические операции and, or и not в Python.
Синтаксис:x or y x and y not x x and y and not z x and (y or z)
Важно! Операторы and
и or
закорачивают вычисление своих операндов (т.е. используют замыкания): правый операнд вычисляется лишь в том случае, если его значение необходимо для получения истинного значения в операциях and
или or
. Другими словами, замыкания в логических операциях используются для запуска второй части или последующих частей логического выражения только в том случае, если это актуально!
or
— оценивает второй аргумент, только если первый равенFalse
. Если какой либо операнд в цепочкеor
является истиной, немедленно возвращается результат — первое истинное значение.and
— оценивает второй аргумент, только если первый равенTrue
. Если в цепочкеand
все операнды являются истиной, результатом будет последнее значение. А если какой-либо из операндов являетсяFalse
, результатом будет первое ложное значение.not
имеет более низкий приоритет, чем операторы сравнения, такnot a == b
интерпретируется какnot (a == b)
, а выражениеa == not b
вовсе является синтаксической ошибкой. Единственный логический оператор с одним аргументом. Он принимает один аргументx
и возвращает противоположный результат:False
для истинного значения иTrue
для ложного значения.
Операторы and
и or
не приводят свои результаты принудительно к значениям True
или False
, а возвращают один из своих операндов. Такой подход позволяет использовать эти операторы в более общих, а не только булевых операциях. Если другие операторы, прежде чем выполнить операцию, вычисляют все свои операнды, то в случае операторов
и or
с их семантикой закорачивания необходимость вычисления правого операнда определяется результатом вычисления левого.
Из булевых операторов, not
имеет самый высокий приоритет, а or
самый низкий, так что A and not B or C
эквивалентно (A and (not B)) or C
. Как всегда, скобки могут быть использованы для выражения желаемого приоритета в операциях.
Логические операции, упорядоченные по приоритету выполнения:
not x
— еслиx
ложно, то возвращаетсяTrue
, иначеFalse
.x and y
— еслиx
ложно, то возвращаетсяx
, иначеу
.x or y
— еслиx
ложно, то возвращаетсяу
, иначеx
Объяснение работы замыкания c оператором
and
:a = 'a' b = 'b' c = 'c' >>> a and b # 'b' >>> '' and b # '' >>> a and b and c # 'c'
Пояснения к примеру выше с оператором and
:
- Оператор
and
вычисляет значения в булевом контексте слева направо. Значения0
,''
,[]
,()
,{}
иNone
являются ложью, все остальное является истиной. Если уand
оба операнда являются истиной, результатом будет последнее значение. - Если какой-либо из операндов является ложью, результатом будет первое такое значение. В данном случает это
''
— пустая строка, первое значение которое является ложью. - Все значения являются истиной, так что в результате мы получаем последнее
c
.
Объяснение работы замыкания c оператором
or
:a = 'a' b = 'b' >>> a or b # 'a' >>> '' or b # 'b' >>> '' or [] or {} # {} >>> def func(): ... return 1 >>> a or func() # 'a'
Пояснения к примеру выше с оператором or
:
- Оператор
or
вычисляет значения в булевом контексте слева направо. Если операнд является истиной,or
немедленно возвращает результат. В данном случаеa
, первое истинное значение. or
вычисляет выражение''
, которое является ложью, затем b, которое является истиной, и возвращает его значение.- Если все значения являются ложью,
or
возвращает последнее. - Обратите внимание, что
or
вычисляет операнды до тех пор, пока не найдет истинное значение, остальное игнорируется. Это имеет значение, когда вычисление операнда дает сторонние эффекты. В данном случае функцияfunc()
не вызывается, так как для получения результата выражения с операторомor
достаточно того, что первый операндa
является истиной.
and
и or
:>>> a = 'one' >>> b = 'two' >>> 1 and a or b # 'one' >>> 0 and a or b # 'two' >>> a = '' >>> b = 'two' # 'a' - пустая строка, которую Python считает ложью, # следовательно 1 and '' дает '', а '' or 'two' дает 'two'. >>> 1 and a or b # 'two'
Внимание! Замыкания в операциях
and
иor
можно использовать с пользой в вычислениях для экономии ресурсов, сокращения времени выполнения и т.д., только будьте осторожны! Необходимо четко понимать как работают замыкания в операторахand
иor
.
- Экономия ресурсов и времени выполнения при помощи
and
; - Проверка предварительных условий перед выражением;
- Определение значения по умолчанию при помощи
or
; - Пример использования замыканий в функциях
all()
иany()
.
Экономия ресурсов и времени выполнения при помощи
and
.Рассмотрим реальный пример из модуля base64
стандартной библиотеки Python, который использует замыкание в оператора if
. Исследуем функцию b64decode
, которая берет строку (или объект, подобный байтам) и декодирует ее:
# взято из Lib/base64. py def b64decode(s, altchars=None, validate=False): """Decode the Base64 encoded bytes-like object or ASCII string s. [docstring cut for brevity] """ s = _bytes_from_decode_data(s) if altchars is not None: altchars = _bytes_from_decode_data(altchars) assert len(altchars) == 2, repr(altchars) s = s.translate(bytes.maketrans(altchars, b'+/')) # использование замыкания с оператором `and` if validate and not re.fullmatch(b'[A-Za-z0-9+/]*={0,2}', s): raise binascii.Error('Non-base64 digit found') return binascii.a2b_base64(s)
Смотрим на оператор if
, который помечен комментарием. В условии сначала проверяется аргумент validate
, а только потом результат работы функции re.fullmatch()
. Аргумент validate
сообщает функции, хочет ли пользователь вообще проверять строку, которую нужно декодировать. Обратите внимание, что если validate=False
то сопоставление регулярного выражения не запускается (срабатывает замыкание). Если порядок операндов поменять, то результат остался такой же, но было бы потрачено гораздо больше времени.
Проверка предварительных условий перед выражением.
Другой типичный шаблон использования замыканий проявляется, когда перед определенной операцией, которая может вызвать исключение, нужно что-то проверить.
Допустим есть последовательность и нужно взять элемент по индексу, но последовательность может оказаться пустой или ее длина может быть меньше индекса. Например:
>>> lst = [0, 1, 2] >>> lst[3] # Traceback (most recent call last): # File "<stdin>", line 1, in <module> # IndexError: list index out of range
Используем проверку предварительных условий:
>>> lst = [0, 1, 2] >>> if lst and len(lst) >=3: ... lst[3]
Здесь, в условии сначала проверяется что список НЕ пустой и только после этого вычисляется длинна этого списка. Если список пустой, то его длина проверяться не будет и условие if
завершиться.
Еще один пример из модуля enum
:
# взято из Lib/enum.py def _create_(cls, class_name, names, *, module=None, qualname=None, type=None, start=1): """ Convenience method to create a new Enum class. """ # [сокращено для краткости] # special processing needed for names? if isinstance(names, str): names = names.replace(',', ' ').split() # смотрим на следующие условие if isinstance(names, (tuple, list)) and names and isinstance(names[0], str): original_names, names = names, [] last_values = [] # [сокращено для краткости]
Более длинный оператор if
содержит три выражения, разделенных операторами and
, и первые два выражения нужны для того, чтобы убедиться, можно ли безопасно выполнить последнее.
isinstance(names, (tuple, list))
— проверяет, является лиnames
кортежем или списком. Если не является то условие завершается.- далее
names
проверяется пусто оно или нет. Если элементов нет то условие завершается. - если
names
не пустой, то можно безопасно выполнить последнюю проверку, связанную с индексациейnames[0]
, а именноisinstance(names[0], str)
.
Определение значения по умолчанию при помощи
or
.Замыкание с помощью логического оператора or
может использоваться для присвоения переменным значений по умолчанию. Вот пример:
# test.py greet = input("Ваше имя >> ") or "незнакомец" print(f"Привет, {greet}!") # $python3 -i test.py # Ваше имя >> # Привет, незнакомец!
Если запустить этот пример и ничего не вводя нажать Enter, то получим вывод «Привет, незнакомец!». Что тут происходит? Если ничего не вводить и нажать Enter, то функция input()
вернет пустую строку ''
, что является False
. Следовательно, оператор or
видит ложное значение слева и должен оценить правый операнд. Для определения окончательное значение выражения or
оценивает правый операнд и если он True
, то возвращает его значение.
Еще пример присвоения значение по умолчанию (используя or
) для изменяемого аргумента из стандартной библиотеки Python.
# взято из Lib/cgitb.py class Hook: """A hook to replace sys.excepthook that shows tracebacks in HTML.""" def __init__(self, display=1, logdir=None, context=5, file=None, format="html"): self.display = display # send tracebacks to browser if true self.logdir = logdir # log tracebacks to files if not None self.context = context # number of source code lines per frame self.file = file or sys.stdout # <= смотрите сюда self.format = format
Этот код взят из модуля cgitb
и определяет sys.stdout
как значение по умолчанию для переменной self.file
. Определение функции __init__
имеет file=None
в качестве ключевого аргумента, так почему бы просто не написать file=sys.stdout
?
Проблема в том, что sys. stdout
может быть изменяемым объектом, поэтому использование file=sys.stdout
в качестве ключевого аргумента со значением по умолчанию не будет работать так, как ожидается. Это легче продемонстрировать со списком в качестве аргумента по умолчанию, хотя принцип тот же:
>>> def addend(val, l=[]): ... l.append(val) ... print(l) >>> addend(3, [1, 2]) # [1, 2, 3] >>> addend(5) # [5] >>> addend(5) # [5, 5] >>> addend(5) # [5, 5, 5]
Обратите внимание на три последовательных вызова addend(5)
. Ожидается, что вызов addend(5)
со значением по умолчанию l=[]
будет вести себя одинаково, но т.к. список является изменяемым объектом, то вызовы добавляют значения val
к значению по умолчанию []
, при этом список растет! Дополнительно смотрите материал «Список Python как аргумент по умолчанию».
Пример использования замыканий
or
и and
в функциях all()
и any()
.Если в выражении генератора использовать оператор моржа :=
, и принимать во внимание тот факт, что функции all()
и any()
также используют замыкания, то можно использовать следующую конструкцию для извлечения первого истинного элемента.
any(predicate(witness := item) for item in items)
Другими словами, если какой-либо элемент item
удовлетворяет условию в функции predicate()
, то переменная witness
сохранит его значение!
Например, если последовательность содержит много целых чисел, как выяснить, есть ли там какие-либо нечетные числа, и как вывести первое из них?
items = [14, 16, 18, 20, 35, 41, 100] any_found = False for item in items: any_found = item % 2 if any_found: print(f"Найдено нечетное число {item}.") break
Теперь все это сравним со следующим кодом:
>>> items = [14, 16, 18, 20, 35, 41, 100] >>> is_odd = lambda x: x % 2 >>> if any(is_odd(witness := item) for item in items): . .. print(f"Найдено нечетное число {witness}.") # Найдено нечетное число 35.
Почему я получаю предупреждение о том, что «целочисленные операнды требуются для оператора двоеточия при использовании в качестве индекса»? — Ответы MATLAB
1,405 просмотров (последние 30 дней)
Прокомментировал: Steven Lord 4 апреля 2023 г.
Ответ принят: Группа поддержки MathWorks
Почему я получаю следующее сообщение об ошибке:
ОШИБКА: Предупреждение. Целочисленные операнды требуются для оператора двоеточия при использовании в качестве индекса.
Ответ принят
Отредактировано: группа поддержки MathWorks 17 ноя 2021
- IntegerOperandsRequired.m.exe
- IntegerOperandsRequired.m.exe
Объяснение:
Вы использовали нецелочисленное значение в качестве одного из параметров (начальное значение, приращение или конечное значение) для оператора двоеточия (:) при его использовании для создания вектора индексов для ссылки в функцию.
Распространенные причины:
Вы выполнили вычисления для получения начального или конечного значения для индексации, но результат этих вычислений не был точно целым числом.
Решение:
Измените вычисления индекса с помощью функций FIX, FLOOR, CEIL или ROUND, чтобы индексы были целыми числами. Вы можете проверить, содержит ли переменная целое число, сравнив переменную с выходными данными функции ОКРУГЛ, работающей с этой переменной, когда MATLAB находится в режиме отладки в строке, содержащей переменную.
https://www.mathworks.com/help/matlab/ref/fix.html
https://www.mathworks.com/help/matlab/ref/floor.html
https://www.mathworks.com/help/matlab/ref/floor.html mathworks.com/help/matlab/ref/ceil.html
https://www.mathworks.com/help/matlab/ref/round.html
Пример, демонстрирующий эту ошибку:
IntegerOperandsRequired.m
Больше ответов (3)
Одно дополнение, что это не ошибка, но это действительно раздражает и отнимает много времени!!! Я попытался воссоздать это предупреждение в своем коде, время выполнения изменилось примерно со 150 с до 3000 с! С этой точки зрения, это предупреждение является более серьезным, чем ошибка для эффективного скрипта.
Спасибо за ответ, это работает!!! Для меня моим решением было просто обернуть рассматриваемую математику полом, например. —
- (Исходная ошибка) z = y(1:x)
- (Исправлено — Работает) z = y(1:floor(x))
Спасибо!
Если «fix», «floor», «ceil» и «round» не разрешаются, можно попробовать использовать «int16».
Произошла ошибка
Не удалось выполнить действие из-за изменений, внесенных на страницу. Перезагрузите страницу, чтобы увидеть ее обновленное состояние.
Выберите веб-сайт
Выберите веб-сайт, чтобы получить переведенный контент, где он доступен, и увидеть местные события и предложения. В зависимости от вашего местоположения мы рекомендуем вам выбрать: .
Вы также можете выбрать веб-сайт из следующего списка
Америка
- Латиноамериканская Америка (Испания)
- Канада (английский)
- США (английский)
Европа
- Бельгия (английский)
- Дания (английский)
- Германия (нем. )
- Испания (Испания)
- Финляндия (английский)
- Франция (французский)
- Ирландия (английский)
- Италия (итальяно)
- Люксембург (английский)
- Нидерланды (английский)
- Норвегия (английский)
- Австрия (немецкий)
- Португалия (английский)
- Швеция (английский)
- Швейцария
- немецкий
- Английский
- французский
- Великобритания (Английский)
Азиатско-Тихоокеанский регион
- Австралия (английский)
- Индия (английский)
- Новая Зеландия (английский)
- 中国
- 简体中文Китайский
- Английский
- 日本Японский (日本語)
- 한국Корейский (한국어)
Обратитесь в местный офис
15.4: Операторы и операнды — Engineering LibreTexts
- Последнее обновление
- Сохранить как PDF
- Идентификатор страницы
- 15358
- Аллен Б. Дауни
- Колледж Олин через Green Tea Press 9002 3
Операторы — это специальные символы, которые представляют такие вычисления, как сложение и умножение. Значения, к которым применяется оператор, называются операндами .
9 используется для возведения в степень, но в Python это побитовый оператор XOR. В этой книге я не буду рассматривать побитовые операторы, но вы можете прочитать о них на http://wiki.python.org/moin/BitwiseOperators.В Python 2 оператор деления может делать не то, что вы ожидаете:
>>> минута = 59 >>> минут/60 0
Значение минуты
равно 59, а в обычной арифметике 59, деленное на 60, равно 0,98333, а не 0. Причина несоответствия в том, что Python выполняет этаж отдел . Когда оба операнда являются целыми числами, результат также является целым числом; деление пола отсекает дробную часть, поэтому в этом примере она округляется до нуля.
В Python 3 результатом этого деления является число с плавающей запятой
. Новый оператор // выполняет деление этажей.
Если любой из операндов является числом с плавающей запятой, Python выполняет деление с плавающей запятой, и результатом является число с плавающей запятой
:
>>> минут/60,0 0,98333333333333328
Эта страница под названием 15.4: Операторы и операнды распространяется под лицензией CC BY-NC-SA 3.0, ее автором, ремиксом и/или куратором является Аллен Б. Дауни (Green Tea Press).
- Наверх
- Была ли эта статья полезной?
- Тип изделия
- Раздел или страница
- Автор
- Аллен Б. Дауни
- Лицензия
- СС BY-NC-SA
- Версия лицензии
- 3,0
- Показать оглавление
- нет
- Метки