Какие основные логические команды используются в ассемблере. Как работают команды AND, OR, XOR и NOT. Для чего применяются логические операции в программировании на ассемблере. Какие особенности нужно учитывать при использовании логических инструкций.
Основные логические команды в ассемблере
В ассемблере используется несколько ключевых логических команд для выполнения побитовых операций над данными:
- AND — логическое И
- OR — логическое ИЛИ
- XOR — исключающее ИЛИ
- NOT — логическое НЕ
Эти команды позволяют манипулировать отдельными битами в регистрах и ячейках памяти, что часто используется для оптимизации кода и реализации различных алгоритмов.
Как работает команда AND
Команда AND выполняет побитовое логическое умножение двух операндов. Результат операции AND для каждой пары битов определяется по следующим правилам:
- 0 AND 0 = 0
- 0 AND 1 = 0
- 1 AND 0 = 0
- 1 AND 1 = 1
То есть результат равен 1 только если оба исходных бита равны 1. Во всех остальных случаях результат 0.
Пример использования команды AND:
«`assembly MOV AL, 10110011b ; AL = 10110011 AND AL, 11001100b ; AL = 10000000 «`В этом примере команда AND обнуляет все биты в регистре AL, кроме самого старшего.
Особенности работы команды OR
Команда OR выполняет побитовое логическое сложение операндов. Правила выполнения операции OR следующие:
- 0 OR 0 = 0
- 0 OR 1 = 1
- 1 OR 0 = 1
- 1 OR 1 = 1
То есть результат равен 1, если хотя бы один из исходных битов равен 1.
Пример использования OR:
«`assembly MOV AL, 10110011b ; AL = 10110011 OR AL, 11001100b ; AL = 11111111 «`Здесь команда OR устанавливает все биты регистра AL в 1.
Принцип действия команды XOR
Команда XOR (исключающее ИЛИ) выполняет операцию сложения по модулю 2. Правила для XOR:
- 0 XOR 0 = 0
- 0 XOR 1 = 1
- 1 XOR 0 = 1
- 1 XOR 1 = 0
Результат равен 1 только если исходные биты различны. Если они одинаковы — результат 0.
Пример использования XOR:
«`assembly MOV AL, 10110011b ; AL = 10110011 XOR AL, 11001100b ; AL = 01111111 «`В этом примере XOR инвертирует старший бит и не меняет младший.
Применение команды NOT
Команда NOT выполняет побитовую инверсию (отрицание) операнда. Она меняет все 0 на 1 и все 1 на 0.
Пример использования NOT:
«`assembly MOV AL, 10110011b ; AL = 10110011 NOT AL ; AL = 01001100 «`Здесь команда NOT инвертирует все биты в регистре AL.
Области применения логических команд
Логические команды в ассемблере используются для решения различных задач:
- Установка и сброс отдельных битов
- Проверка значений битов
- Маскирование битов
- Упаковка и распаковка данных
- Оптимизация вычислений
- Реализация криптографических алгоритмов
Например, с помощью AND можно обнулить определенные биты, сохранив остальные. OR позволяет установить нужные биты в 1. XOR часто применяется для быстрого шифрования данных.
Особенности использования логических инструкций
При работе с логическими командами в ассемблере важно учитывать следующие моменты:
- Размер операндов должен совпадать (8, 16 или 32 бита)
- Результат всегда сохраняется в первом операнде
- Операции влияют на флаги процессора (ZF, SF, PF)
- Флаги CF и OF всегда сбрасываются в 0
- Второй операнд может быть константой (кроме NOT)
Также нужно помнить, что логические операции выполняются над всеми битами операндов одновременно.
Примеры использования логических команд
Рассмотрим несколько практических примеров применения логических инструкций в ассемблере:
«`assembly ; Обнуление младших 4 бит MOV AL, 11110000b AND AL, 11110000b ; AL = 11110000 ; Установка старшего бита MOV AL, 01111111b OR AL, 10000000b ; AL = 11111111 ; Инверсия 5-го бита MOV AL, 10101010b XOR AL, 00010000b ; AL = 10111010 ; Проверка четности числа MOV AL, 5 TEST AL, 1 ; ZF = 0 (число нечетное) ; Быстрое обнуление регистра XOR EAX, EAX ; EAX = 0 «`Эти примеры демонстрируют типичные способы применения логических команд для манипуляции битами и оптимизации кода.
Влияние логических операций на флаги
Выполнение логических команд влияет на некоторые флаги процессора:
- ZF (Zero Flag) — устанавливается, если результат равен 0
- SF (Sign Flag) — равен старшему биту результата
- PF (Parity Flag) — устанавливается при четном количестве единичных битов
- CF (Carry Flag) — всегда сбрасывается в 0
- OF (Overflow Flag) — всегда сбрасывается в 0
Эти флаги можно использовать для анализа результата операции и организации условных переходов.
Оптимизация кода с помощью логических команд
Логические инструкции позволяют оптимизировать некоторые вычисления:
- Умножение на степень двойки: сдвиг влево (SHL)
- Деление на степень двойки: сдвиг вправо (SHR)
- Проверка на четность: AND с 1
- Быстрое обнуление регистра: XOR с самим собой
- Смена знака числа: NOT и прибавление 1
Такие оптимизации позволяют ускорить выполнение программы за счет замены медленных арифметических операций на быстрые логические.
Заключение
Логические команды являются важным инструментом в арсенале программиста на ассемблере. Они позволяют эффективно манипулировать отдельными битами данных, что часто используется для оптимизации кода и реализации различных алгоритмов. Понимание принципов работы логических инструкций и умение их правильно применять — ключ к написанию эффективного низкоуровневого кода.
Логические операции в Assembler — CodeTown.ru
Здравствуйте, уважаемые читатели. Сегодня мы поговорим об основных логических операциях в Assembler, и по традиции, разберем практический пример.
Известные всем логические операторы и в Assembler выполняют практически такие же функции. Мы рассмотрим самые основные и наиболее используемые:
Логическое побитовое И
В Assembler этот оператор сравнивает два регистра по одному биту. Он обозначается как and, и вот пример синтаксиса:;пример логического И в Assembler
mov bx, 01101001b
mov bl, 01000111b
and bx, bl
Очевидно, что результатом этой операции будет 01000001, но возникает один вопрос: куда записывается результат выполнения оператора?
Так вот, результат записывается в регистр, который стоит первым после оператора and, в нашем случае — это регистр bx, то есть теперь его значение поменялось на 01000001.
Логическая инструкция test
Во многих случаях нам бы не хотелось, чтобы число переписывалось и теряло своего первоначального значения. Именно для этого предусмотрели логическую инструкцию test. Она как и and производит побитовое умножение, но не записывает результат в какой либо регистр, а всего лишь поднимает флаги для каждого бита, то есть она имитирует выполнение инструкции and. И для лучшего восприятия мы рассмотрим пример на проверку четности числа с помощью логических операций в Assembler:
.386 .model flat,stdcall option casemap:none include ..\INCLUDE\kernel32.inc include ..\INCLUDE\user32.inc includelib ..\LIB\kernel32.lib includelib ..\LIB\user32.lib .data yes db "Chetnoe" no db "Ne chetnoe" stdout dd ? cWritten dd ? .code start: invoke GetStdHandle, -11 ; дескриптор вывода mov stdout,eax ; по умолчанию помещается в eax mov ah, 23 test ah, 00000001b ; сравниваем последний бит числа jz evn invoke WriteConsoleA, stdout, ADDR no, sizeof no, ADDR cWritten, 0 jmp exit evn: invoke WriteConsoleA, stdout, ADDR yes, sizeof yes, ADDR cWritten, 0 exit: invoke ExitProcess,0 end start
Число, которое мы проверяем на четность, помещаем в регистр ah, затем сравниваем последний бит числа с единицей, и если вернется единица, то число нечетное, а если ноль — четное, что соответственно выводится на экран. Напомню, что команда jz отвечает за условный переход на метку (метка evn), а команда jmp — за безусловный переход.
Логическое побитовое ИЛИ
В Assembler логическое побитовое ИЛИ обозначается or, и синтаксис идентичен синтаксису команды and, по своей сути представляет побитовое сложение.;пример логического ИЛИ в Assembler
mov bx, 01101001b
mov bl, 01000111b
or bx, bl
Выполнение этой инструкции вернет 01101111 и поместит это двоичное число в регистр bx.
Логическое исключающее ИЛИ
Также помимо логического ИЛИ, часто используют исключающее ИЛИ в Assembler. Оно обозначается командой xor и выделяет различия в регистрах, то есть, если в одном бите содержится 1, а в другом 0, то xor вернет 1, если же в битах содержатся одинаковые значения, то xor вернет 0.
Разберем на примере, за основу возьмем предыдущий пример проверки на четность:
. 386 .model flat,stdcall option casemap:none include ..\INCLUDE\kernel32.inc include ..\INCLUDE\user32.inc includelib ..\LIB\kernel32.lib includelib ..\LIB\user32.lib .data yes db "Chetnoe" no db "Ne chetnoe" stdout dd ? cWritten dd ? .code start: invoke GetStdHandle, -11 ; дескриптор вывода mov stdout,eax ; по умолчанию помещается в eax xor ah, ah ; обнуление регистра ah xor al, al or ah, 21 ; помещаем в регистр число 21 or al, 20 xor ah, al xor al, ah xor ah, al ; конструкция для смены значений регистров test ah, 00000001b jz evn invoke WriteConsoleA, stdout, ADDR no, sizeof no, ADDR cWritten, 0 jmp exit evn: invoke WriteConsoleA, stdout, ADDR yes, sizeof yes, ADDR cWritten, 0 exit: invoke ExitProcess,0 end start
Конструкция из 3 xor позволяет поменять значения в регистрах, и по окончании в регистре ah будет содержаться число 20. Затем выведется сообщение о том, что число четное.
Также отметим конструкцию xor ah, ah
— она позволяет обнулить регистр. По сути это аналог команды mov ah, 0
, но программисты любят использовать именно эту конструкцию, так как она занимает всего 2 байта, а команда mov — 5 байт.
Заключение
В этой статье мы поговорили и разобрали основные моменты работы с логическими инструкциями и операциями в Assembler, не забывайте скачивать и просматривать исходники, а также оставляйте ваши комментарии.
Скачать исходник 1
Скачать исходник 2
Логическое ИЛИ
Английский за 3 месяца
Хотим мы того или нет, но английский язык стал международным средством общения. В Европе он входит в школьную программу, причём на таком уровне, что после школы все дети умеют достаточно хорошо говорить на английском. Это надо просто принять как данность и использовать. Лишать себя возможности быть частью мирового сообщества, это, как минимум, недальновидно. Подробнее… |
Операция логического ИЛИ в Ассемблере выполняется с помощью команды OR. Эта команда выполняет логическое ИЛИ между всеми битами двух операндов. Результат записывается в первый операнд. Синтаксис:
OR ЧИСЛО1, ЧИСЛО2
В зависимости от результата могут быть изменены флаги ZF, SF, PF. Флаги OF и CF всегда сбрасываются.
ЧИСЛО1 может быть одним из следующих:
- Область памяти (MEM)
- Регистр общего назначения (REG)
ЧИСЛО2 может быть одним из следующих:
- Область памяти (MEM)
- Регистр общего назначения (REG)
- Непосредственное значение (IMM)
С учётом ограничений, которые были описаны выше, комбинации ЧИСЛО1-ЧИСЛО2 могут быть следующими:
REG, MEM MEM, REG REG, REG MEM, IMM REG, IMM
Когда мы изучали команду AND, то мы узнали, что с её помощью можно преобразовать маленькую букву в большую, используя битовую маску.
Инструкция OR поступает наоборот — она может преобразовать большую букву в маленькую:
MOV AL, 'A' ; AL = 01000001b AND AL, 00100000b ; AL = 01100001b ('a')
Размер обоих операндов должен быть одинаковым: 8, 16 или 32 разряда.
Команда OR обычно используется для установки в единицу отдельных битов двоичного числа (например, флагов состояния процессора) по заданной маске.
Если бит маски равен нулю, то значение соответствующего бита числа не изменяется, а если равен 1, то устанавливается в 1.
Ниже показано, как можно установить четыре младших бита числа:
0 0 1 1 1 0 1 1 - Исходное значение 0 0 0 0 1 1 1 1 - Битовая маска 0 0 1 1 1 1 1 1 - Результат
В результате четыре младших бита будут установлены в любом случае, независимо от того, какое состояние у них было в исходном значении (выделены красным цветом). Старшие четыре бита не изменятся, то есть будут такими же, как у исходного значения.
Ещё одно применение инструкции OR — это преобразование двоичной цифры от 0 до 9 в значение, которое соответствует ASCII-коду символа, обозначающему эту цифру. Для этого нужно установить в единицу биты 4 и 5.
Пример:
0 0 0 0 0 1 0 1 - Исходное значение: число 5 0 0 1 1 0 0 0 0 - Битовая маска (биты 4 и 5 установлены) 0 0 1 1 0 1 0 1 - Результат: 35h - ASCII-код символа 5
Пример программы:
.model tiny .code ORG 100h start: MOV AX, 0B800h ;установить AX = B800h (память VGA). MOV DS, AX ;копировать значение из AX в DS. MOV CL, 'A' ;CL = 41h (ASCII-код символа 'A'). MOV CH, 01001110b ;CH = атрибуты цвета (желтый текст на красном фоне). MOV BX, 72eh ;BX = позиция на экране = 2*(x + y*80) = (39, 11). MOV [BX], CX ;[0B800h:015Eh] = CX (записать символ в видеопамять). OR CL, 00100000b ;Теперь CL = 61h (ASCII-код символа 'a'). MOV BX, 730h ;BX = позиция на экране = 2*(x + y*80) = (40, 11). MOV [BX], CX ;[0B800h:015Eh] = CX (записать символ в видеопамять). MOV CL, 5 ;Записать число в регистр CL OR CL, 00110000b ;Преобразовать в ASCII-код MOV AX, 0B800h ;установить AX = B800h (память VGA). MOV DS, AX ;копировать значение из AX в DS. MOV CH, 01001110b ;CH = атрибуты цвета (желтый текст на красном фоне). MOV BX, 732h ;BX = позиция на экране = 2*(x + y*80) = (41, 11). MOV [BX], CX ;[0B800h:015Eh] = CX (записать символ в видеопамять). END start
Как было сказано, команда OR выполняет операцию логического сложения (логического ИЛИ) между всеми битами двух чисел. Таблица истинности для операции логического сложения выглядит следующим образом:
0 И 0 = 0 0 И 1 = 1 1 И 0 = 1 1 И 1 = 1
Логическое ИЛИ — это операция логического сложения. Чтобы легче было запомнить таблицу истинности для логического ИЛИ, вспомните математику:
0 + 0 = 0 0 + 1 = 1 1 + 0 = 1 1 + 1 = 1
Последний случай вас, возможно, смутит. Но на самом деле всё в порядке ))) Просто по правилам булевой алгебры при логическом сложении результат равен нулю, если все операнды равны нулю. Во всех остальных случаях результат равен 1.
Подписаться на Дзен-канал
Вступить в группу «Основы программирования» Подписаться на рассылки по программированию |
Первые шаги в программирование
Главный вопрос начинающего программиста – с чего начать? Вроде бы есть желание, но иногда «не знаешь, как начать думать, чтобы до такого додуматься». У человека, который никогда не имел дело с информационными технологиями, даже простые вопросы могут вызвать большие трудности и отнять много времени на решение. Подробнее… |
Введение в микропроцессорные системы – UW–Madison
Обзор
Архитектура Cortex-M поддерживает общие арифметические и логические инструкции, которые можно использовать для изменения содержимого регистров общего назначения. Большинство инструкций в архитектуре Cortex-M представляют собой инструкции с одним циклом.
В дополнение к арифметическим операциям поддерживаются различные логические операции. Наиболее распространенными являются AND, ORR, MVN (логическое НЕ), EOR (исключающее ИЛИ). Логические операции обычно используются для установки (сделать бит равным 1) или очистить (сделать бит равным 0) определенного бита в регистре. Каждая операция является 32-битной операцией. Например, предположим, что R0 = 0xFFFF3333 и R1 = 0xFF00FF00. Если мы И R0 и R1 результат будет 0xFF003300
1111 1111 1111 1111 0011 0011 0011 0011 (R0) & 1111 1111 0000 0000 1111 1111 0000 0000 (R1) 1111 1111 0000 0000 0011 0011 0000 0000 (Результат)
Синтаксис
Общий синтаксис арифметических/логических инструкций следующий:
Rd, Rn,
Гибкий второй операнд поддерживает сложение двух регистров вместе или добавление непосредственного значения в один регистр. Непосредственные значения должны начинаться с #. Непосредственные значения могут быть записаны в десятичном, шестнадцатеричном и редко двоичном формате.
ДОБАВИТЬ R2, R1, R0 ; Р2 = Р1 + Р0 ДОБАВИТЬ R2, R2, #1 ; R2 = R2 + 1 (немедленное десятичное число) И R2, R2, #0xFF ; R2 = R2 и 0x000000FF (шестнадцатеричный непосредственный) И R2, R2, #2_0011 ; R2 = R2 и 0x00000003 (двоичный немедленный)
Immediates
Когда вы начнете писать ассемблерный код для ARM, вы, несомненно, столкнетесь с некоторыми ошибками ассемблера из-за недопустимых immediates. Хорошим вопросом будет: «Почему некоторые немедленные действия действительны, а другие недействительны?». Ответ на этот вопрос связан с тем фактом, что архитектура ARM является архитектурой RISC. Это означает, что все ассемблерные инструкции кодируются в машинную инструкцию (0 или 1) фиксированной длины. В нашем случае эта длина может быть 16 или 32 бита. Если в инструкции указан целевой регистр, исходный регистр и 32-битное непосредственное значение, как вся информация будет закодирована в 32-битной машинной инструкции? Ответ заключается в том, что это невозможно. Нам потребуются все 32 бита только для указания непосредственного, не оставив места для кода операции и другой информации, необходимой для определения исходного и целевого регистров.
Что ARM решила сделать, так это ограничить, какие немедленные действия действительны. Действительные немедленные действия могут принимать одну из 4 форм.
- Любое непосредственное значение, которое может быть получено путем сдвига 8-битного значения влево на любое количество битов в 32-битном слове ( X и Y — любое шестнадцатеричное число)
- Любое непосредственное значение в формате 0x00XY00XY
- Любое непосредственное значение в формате 0xXY00XY00
- Любое непосредственное значение в формате 0xXYXYXYXY
Более подробное описание того, почему ARM решила использовать 8-битное значение с 4-битным кодом сдвига, см. по следующей ссылке.
Подпись Против. Числа без знака
Числа, которыми манипулирует микропроцессор, могут рассматриваться как числа без знака или числа со знаком. Беззнаковые числа используют все биты числа для представления положительного числа. Регистры в архитектуре Cortex-M имеют ширину 32 бита, но в следующих примерах для простоты будут рассмотрены 8-битные числа.
Если бы регистр содержал значение 11111101 2 , то это значение представляло бы десятичное значение 253 (1×2 7 + 1×2 6 +1×2 5 + 1×2 4 +1×2 3 + 1×2 2 +0×2 6 0 5 0 9 0
+ 0 1 1 ). Это связано с тем, что беззнаковое число использует все биты для представления положительного числа. Используя то же значение 11111101 2 , какое десятичное значение будет представлять это число для числа со знаком? Ответ -3.Числа со знаком — это целые числа, которые могут быть как положительными, так и отрицательными числами. Положительные числа со знаком всегда начинаются с 0 как старшего разряда, и их величина может быть определена так же, как и беззнаковое число. Числа со знаком представлены с использованием представления дополнительных чисел 2. Дополнение отрицательного числа 2 всегда будет начинаться со старшего бита, равного 1. Чтобы вычислить величину отрицательного числа, вы можете инвертировать все биты в числе и добавить к нему единицу.
11111101 ? Побитовый комплимент(11111101) + 1 ? 00000010 + 1 ? 00000011 (-3 10 )
Причина, по которой в микропроцессорах используются дополнительные числа 2, заключается в том, что вычитание с использованием дополнительных чисел 2 на самом деле то же самое, что и сложение. Следующие примеры продемонстрируют это.
2 00000010 + 3_ + 00000011 00000101 (5 10 ) 2 00000010 -3_ + 11111101 11111111111111111111111111111111111111111111111111111111111111111111111111111111111000000100 + 1? (-1 10 )Инициализация реестра общего назначения
Чтобы инициализировать регистр. Инструкция MOV устанавливает значение целевого регистра в значение другого регистра ИЛИ может установить его в значение непосредственного. Инструкции MOV могут поддерживать любой 16-битный немедленный. Так что же делать, если вы хотите инициализировать регистр 32-битным непосредственным значением, которое не является действительным непосредственным значением? Ответ заключается в использовании команды MOV32. MOV32 — это псевдоинструкция. Псевдоинструкция — это инструкция, поддерживаемая ассемблером, которая на самом деле не поддерживается аппаратным обеспечением. Ассемблер заменяет псевдоинструкцию одной или несколькими поддерживаемыми командами, которые приведут к желаемым результатам. В случае MOV32 ассемблер использует две команды для загрузки 32-битного непосредственного ( MOV и MOVT ).
Необязательный сдвиг второго операнда
Архитектура Cortex-M поддерживает сдвиг второго операнда перед выполнением нужного кода операции. Поддерживается 5 вариантов смены.
- ASR #n (арифметический сдвиг вправо)
- LSL #n (логический сдвиг влево)
- LSR #n (логический сдвиг вправо)
- ROR #n (повернуть вправо)
- RRX (Повернуть вправо на один бит с расширением)
MOV R0, #1 ; R0 = 1 ДВИГАТЕЛЬ R1, #2 ; R1 = 2 ДОБАВИТЬ R1, R1, R0, LSL #2 ; R1 = R1 +(R0<<2)= 2+(1<<2) = 6
См. стр. 28 набора инструкций TI Cortex-M для получения более подробной информации о каждой операции переключения.
Умножение/Деление
Некоторые микроконтроллеры реализуют умножение как многотактовую операцию, а другие вообще не поддерживают встроенную команду умножения. В случае, когда нет встроенной инструкции умножения, компилятор превращает операцию умножения в цикл FOR, который многократно складывает. Архитектура ARM Cortex-M поддерживает 32-битное умножение за один цикл, что помогает повысить общую производительность приложения. Для выполнения операций деления и умножения, размер которых превышает 32 бита, требуется несколько тактов.
Другие команды
Архитектура Cortex-M поддерживает другие инструкции, не упомянутые здесь. Полный список инструкций см. в справочнике по сборке ARM. Если вы хотите увидеть больше примеров, чем те, которые представлены ниже, см. Набор инструкций TI Cortex-M.
Примеры
Допустимые константы
ДОБАВИТЬ R0, R0, #1 ДОБАВИТЬ R0, R0, #0xFF000000 SUB R1, R0, #0xAB00AB00 ДОБАВИТЬ R2, R1, #0x12121212 SUB R2, R0, #0x000FE000
Инициализация регистров общего назначения
MOV R0, #0xFFFF ; Устанавливает биты 15-0 в 0xFFFF MOVT R0, #0xEEEE ; Устанавливает биты 31-16 в 0xEEEE MOV32 R0, #0xEEEEFFFF ; Эквивалентная псевдоинструкция ДВИГАТЕЛЬ R1, R0 ; Инициализация из регистра
Сложение/вычитание
MOV R0, #1 ; R0 = 1 ДВИГАТЕЛЬ R1, #10 ; R1 = 10 ДОБАВИТЬ R2, R1, R0 ; R2 = R1 + R0 (11) SUB R3, R1, R0 ; R3 = R1 - R0 (9)
Добавление больших чисел
;********************************************* ************* ; АЦП Rd, Rn,; Добавить с переносом позволяет добавлять числа больше, чем ; 32 бита ;****************************************************** ***** ; Инициализировать регистры для первого 64-битного числа МВН R0, #0x0 ; Устанавливает R0 равным 0xFFFFFFFF ДВИГАТЕЛЬ R1, #0x0 ; Устанавливает R1 равным 0x00000000 ; Инициализировать регистры для второго 64-битного числа ДВИГАТЕЛЬ R2, #0x1 ; Устанавливает R0 равным 0x00000001 ДВИГАТЕЛЬ R3, #0x1 ; Устанавливает R1 равным 0x00000001 ; 64-битное дополнение ; 0x0000000100000001 ; + 0x00000000FFFFFFFF ДОБАВИТЬ R4, R0, R2 ; R4 содержит SUM[31:0] АЦП R5, R1, R3 ; R5 содержит SUM[63:32]
Умножение/Деление
;************************************************ ************ ; МУЛ Рд, Рн, Рм ; Умножьте два 32-битных числа, результат будет 32-битным ;****************************************************** ***** МОВ Р0, #10 МОВ Р1, #5 МУЛ R2, R1, R0 ;****************************************************** ***** ; МАЛЕНЬКИЙ RdLo, RdHi, Rn, Rm ; Умножьте два 32-битных числа, результат будет 64-битным со знаком ; целое число ;****************************************************** ***** МОВ R0, #0x80000000 МОВ Р1, #8 МАЛЕНЬКИЙ R2, R3, R1, R0 ;****************************************************** ***** ; UMULL RdLo, RdHi, Rn, Rm ; Умножьте два 32-битных числа, результат будет 64-битным беззнаковым ; целое число ;****************************************************** ***** МОВ R0, #0x80000000 МОВ Р1, #8 УМУЛЛ R2, R3, R1, R0 ;****************************************************** ***** ; SDIV Рд, Рн, Рм ; Разделите два 32-битных числа, результат будет 32-битным со знаком ; целое число ;****************************************************** ***** MOV R1, #0x80000000 МОВ Р0, #8 SDIV R2, R1, R0 ;****************************************************** ***** ; УДИВ Рд, Рн, Рм ; Разделите два 32-битных числа, результат будет 32-битным беззнаковым ; целое число ;****************************************************** ***** MOV R1, #0x80000000 МОВ Р0, #8 УДИВ R2, R1, R0
Очистка битов
; Очистить биты 3:0 MOV R0, #0xFFFF ; Инициализировать R0 до 0x0000FFFF МВН R1, #0x0F ; Установите битовую маску на 0xFFFFFFFF0 И R0, R0, R1 ; Очистить биты 3:0 ; Другой (более эффективный) способ очистки битов 3:0 MOV R0, #0xFFFF ; Инициализировать R0 до 0x0000FFFF БИК R0, R0, #0x0F ; Очистить биты 3:0
Установка битов
; Установите биты 3:0 в значение 1 МОВ R0, #0 ОРР R0, R0, #0xF
Переключение битов
; Переключить (инвертировать) биты 15:8 MOV R0, #0xFF ; Установите R0 в 0x000000FF ; Исключающее ИЛИ будет переключать биты регистра, где ; немедленное значение равно 1. EOR R0, R0, #0xFF00 ; Исключающее ИЛИ приводит к 15:8
Логические инструкции в x86 | Ресурсы Infosec
В этой статье определяются логические инструкции, выполняемые процессорами x86. Далее приводится краткое описание четырех ключевых классификаций логических инструкций.
Эта статья предназначена для студентов и профессионалов, которые хотят получить подробное представление о логических инструкциях, их классификации и способах их использования. Благодаря использованию эмулятора 8086 эта статья поможет вам лучше понять логические инструкции, их синтаксис и, в некоторых случаях, поток памяти во время выполнения.
Логические инструкции в x86
Логические инструкции определяют набор операций, выполняемых арифметико-логическим устройством (АЛУ) процессора. В этой статье будут обсуждаться только четыре ключевые операции логических инструкций: И , ИЛИ , Исключающее ИЛИ и НЕ .
Основной формат инструкций
Таблица 1: Логические инструкции и их основные форматы
Первый операнд в большинстве случаев относится к регистру или памяти. Второй операнд может быть либо в регистре, либо в памяти, либо в постоянном значении.
Инструкция AND
Инструкция AND используется для выполнения операций над битами.
Таблица 2: Возможные бинарные состояния для двух входов
Рисунок 1: и логика имеет состояние выключения, когда оба входа выключены
Рисунок 2: и логика имеет состояние выключения, когда любой из входов выключен
Рисунок 3 Рисунок 3. : Логика И находится в состоянии ВЫКЛ, когда один из входов ВЫКЛ
входы
Следуя рисункам с 1 по 4, можно резюмировать, что операция побитового И возвращает 1, если совпадающие биты обоих входов или операндов равны 1. В противном случае возвращается 0.
Пример 1
- MOV AX , 10100011б ; Скопируйте двоичное значение 10100011 в аккумулятор .
- MOV BX, 00111101b ; Скопируйте двоичное значение 00111101 в регистр BX .
- И AX, BX ; Выполните операцию И над значениями в регистрах AX и BX. Сохранить вывод в аккумуляторе
Операция И выполняется, как показано ниже: ): 0010 0001
Аккумулятор AX будет иметь значение 00100001 после выполнения операции И. Это значение будет храниться в 8-битном младшем регистре AL аккумулятора.
Рисунок 5: Содержимое регистров AX и BX до выполнения операции И
Рисунок 6: Содержимое регистров AX и BX после выполнения операции И
Инструкция ИЛИ
Инструкция ИЛИ используется для выполнения операций над битами. Чтобы понять, как это работает, мы запустим симулятор логического элемента, чтобы сгенерировать возможные выходные состояния логики ИЛИ для двух двоичных входов, A и B. Эти входы также являются операндами. Входы логики ИЛИ такие же, как показано в Таблице 2.
Рис. 7: Логика ИЛИ имеет состояние ВЫКЛ, когда оба входа ВЫКЛ
Рисунок 8: или логика имеет состояние, когда любой из входов на
Рисунок 9: или логика имеет состояние, когда любой из входов на
44 Рисунок 10. Логика ИЛИ имеет состояние ВКЛ, когда оба входа ВКЛ
возвращает 1, если любой из битов на входе равен 1. В противном случае он возвращает 0. Выход возвращает 1, когда оба входа равны 1.
Пример 2
- MOV AX, 10100011b
- ДВИГАТЕЛЬ БХ, 00111101b
- ИЛИ ТОПОР, ВХ
Операция И выполняется, как показано ниже: ): 1011 1111
Аккумулятор AX будет иметь значение 10111111 после выполнения операции ИЛИ. Это значение будет храниться в 8-битном младшем регистре AL аккумулятора.
Рисунок 11: Содержание регистра AX и BX до или работы выполняется
Рисунок 12: Содержимое регистра AX и BX после или операции выполнено
Инструкция
используется для выполнения операций над битами. Мы будем использовать симулятор для генерации возможных выходных состояний логики XOR для двух двоичных входов A и B. Эти входы также представляют операнды инструкций. Входные данные для логики XOR такие же, как показано в таблице 2.
Рис. 13. Логика исключающего ИЛИ имеет состояние ВЫКЛ., когда оба входа ВЫКЛ.
Таблица 5: Выход логики XOR с двумя входами
Следуя рисункам с 13 по 16, можно резюмировать, что операция побитового исключающего ИЛИ возвращает 1, только если любой из битов на входе равен 1. В противном случае она возвращает 0. Выход возвращает 0, когда оба входа равны 1 или 0.
Пример 3
- MOV AX, 10100011b
- ДВИГАТЕЛЬ БХ, 00111101b
- XOR AX, BX
Операция XOR выполняется, как показано ниже:
Operand1 (AX): 1010 0011
Операнд2 (BX): 0011 1101
———————————-
Операнд1(AX): 1001 1110
Аккумулятор AX будет иметь значение 10011110 после выполнения операции XOR. Это значение будет храниться в 8-битном младшем регистре AL аккумулятора.
Рисунок 17: Содержимое регистров AX и BX до выполнения операции XOR
Рисунок 18: Содержимое регистров AX и BX после выполнения операции XOR
Инструкция NOT
Инструкция NOT используется для выполнения операций над битами. Эта инструкция переворачивает биты в операнде. Входы логики НЕ показаны ниже в таблице 6.
Таблица 6. Возможные двоичные состояния для одного входа
Рис. 20. Логика НЕ имеет состояние ВЫКЛ, когда однобитовый вход ВКЛ
Таблица 7. Выход логики НЕ с одним входом
Пример 4
- НЕ AL Операция НЕ выполняется, как показано ниже: будет иметь значение 0101 1100 после выполнения операции НЕ.
Рисунок 21. Содержимое регистра AL до выполнения операции НЕ
Рисунок 22. Содержимое регистра AL после выполнения операции НЕ операции. Чтобы адекватно помочь в понимании того, как работают операции AND, OR, XOR и NOT, в статье также представлен поток инструкций во время их выполнения.