assembler. Учебник для вузов_Юров В.И_2003 -637с (862834), страница 45
Текст из файла (страница 45)
Результат записывается на место операнд_1.Ш or операнд_1,операнд_2 — операция логического сложения. Команда выполняетпоразрядно логическую операцию ИЛИ (дизъюнкцию) над битами операндовоперанд_1 и операнд_2. Результат записывается на место операнд_1.1 96Глава 9. Логические команды и команды сдвигаш хог операнд_1,операнд_2 — операция логического исключающего сложения. Команда выполняет поразрядно логическую операцию исключающего ИЛИ надбитами операндов операнд_1 и операнд_2.
Результат записывается на место операнд_1.и test операнд_1,операнд_2 — операция проверки (способом логического умножения). Команда выполняет поразрядно логическую операцию Я над битами операндов операнд_1 и операнд_2. Состояние операндов остается прежним, изменяются только флаги ZF, SF, и PF, что дает возможность анализировать состояниеотдельных битов операнда без изменения их состояния в исходных операндах.;s: not операнд — операция логического отрицания.
Команда выполняет поразрядное инвертирование (замену значения на обратное) каждого бита операнда.Результат записывается на место операнда.Для представления роли логических команд в системе команд процессора оченьважно понять области их применения и типовые приемы их использования припрограммировании. Далее мы будем рассматривать логические команды в контексте обработки последовательности битов.Очень часто некоторая ячейка памяти должна играть роль индикатора, показывая, например, занятость некоторого программного или аппаратного ресурса. Таккак эта ячейка может принимать только два значения — занято (1) или свободно(0), то отводить под нее целый байт очень расточительно, логичнее для этой целииспользовать бит.
А если таких индикаторов много? Объединив их в пределах одного байта или слова, можно получить довольно существенную экономию памяти.Посмотрим, что могут сделать для этого логические команды.С помощью логических команд возможно выделение отдельных битов в операнде с целью их установки, сброса, инвертирования или просто проверки на определенное значение.
Для организации подобной работы с битами второй операндобычно играет роль маски. Путем установки в 1 битов этой маски и определяютсянужные для конкретной операции биты первого операнда. Покажем, какие логические команды могут применяться для этой цели.Для установки определенных разрядов (битов) в 1 применяется командаor операнд_1,операнд_2В этой команде второй операнд, играющий роль маски, должен содержать единичные биты на месте тех разрядов, которые должны быть установлены в 1 в первом операнде:or е а х .
Ю Ь у с т а н о в и т ь 1-й бит в р е г и с т р е еахДля сброса определенных разрядов (битов) в 0 применяется командаand операнд_1,операнд_2В этой команде второй операнд, играющий роль маски, должен содержать нулевые биты на месте тех разрядов, которые должны быть установлены в 0 в первомоперанде:and е а х , 0 f f f f f f f d h ;сбросить в 0 1-й бит в регистре еахДля выяснения того, какие биты в обоих операндах различаются, или для инвертирования заданных битов в первом операнде применяется командах о г операнд_1,операнд_2Логические команды197Интересующие нас биты маски (второго операнда) при выполнении командыXOR должны быть единичными, остальные — нулевыми:хог еах.ЮЬ инвертировать 1-й бит в регистре еахjz mes;переход, если 1-й бит в al был единичнымДля проверки состояния заданных битов в первом операнде применяется командаtest операнд_1,операнд_2Проверяемые биты первого операнда в маске (втором операнде) должны иметьединичное значение.
Алгоритм работы команды TEST подобен алгоритму работыкоманды A N D , но он не меняет значения первого операнда. Результатом командыявляется установка значения флага нуля ZF:s если ZF = 0, то в результате логического умножения получился ненулевой результат, то есть хотя бы один единичный бит маски совпал с соответствующимединичным битом первого операнда;* если ZF = 1, то в результате логического умножения получился нулевой результат, то есть ни один единичный бит маски не совпал с соответствующим единичным битом первого операнда.Таким образом, если любые соответствующие биты в обоих операндах установлены, то ZF = 0.
Для реакции на результат команды TEST целесообразно использовать команду перехода на метку J N Z (Jump if Not Zero) — переход, если флаг нуляZF ненулевой, или команду с обратным действием JZ GumP if Zero) — переход, еслифлаг нуля ZF нулевой. Например,testeax,00000010hjnz ml ;переход если 4-й бит равен 1Начиная с системы команд процессора 1386, набор команд для поразряднойобработки данных расширился.
При использовании этих команд необходимо указывать одну из директив: .386, .486 и т. д. Следующие две команды позволяют осуществить поиск первого установленного в 1 бита операнда. Поиск можно произвести как с начала, так и от конца операнда:• bsf операнд_1,операнд_2 — сканирование битов вперед (Bit Scaning Forward).Команда просматривает (сканирует) биты второго операнда от младшего к старшему (от бита 0 до старшего бита) в поисках первого бита, установленного в 1.Если таковой обнаруживается, в первый операнд заносится номер этого битав виде целочисленного значения. Если все биты второго операнда равны 0, тофлаг нуля ZF устанавливается в 1, в противном случае флаг ZF сбрасывается в 0.mov al,02hbsf bx.al;bx=lj z ml ;переход, если al=00hli bsr операнд_1,операнд_2 — сканирование битов в обратном порядке (Bit ScaningReset).
Команда просматривает (сканирует) биты второго операнда от старшего к младшему (от старшего бита к биту 0) в поисках первого бита, установленного в 1. Если таковой обнаруживается, в первый операнд заносится номер этого бита в виде целочисленного значения. При этом важно, что позиция первогоединичного бита слева все равно отсчитывается относительно бита 0. Если всебиты второго операнда равны 0, то флаг нуля ZF устанавливается в 1, в противном случае флаг ZF сбрасывается в 0.198Глава 9. Логические команды и команды сдвигаЛистинг 9.1 демонстрирует пример применения команд BSR и BSF. Введите коди исследуйте работу программы в отладчике (в частности, обратите внимание нато, как меняется содержимое регистра ВХ после выполнения команд BSF и BSR).Листинг 9.1. Сканирование битов;prg_9_l.asmmasmmodelsmallstack256.data.codemain:mov ax,@datamov ds.ax.486ml:xor a x , a xmov al,02hbsf bx.axjz mlbsr bx.ax;сегмент данных;сегмент кода;точка входа в программу;это обязательно;bx=l;переход, если al=00hmov ах,4с00п;стандартный выходint 21hend mainИнтерес представляют еще несколько из группы логических команд, позволяющих реализовать доступ к конкретному биту операнда.
Они, как и предыдущие,появились в моделях процессоров Intel, начиная с 1386. Поэтому при их использовании не забывайте указывать одну из директив: .386, .486 и т. д. Операнд можетнаходиться как в памяти, так и в регистре общего назначения. Положение битазадается смещением его относительно младшего бита операнда. Смещение можеткак задаваться в виде непосредственного значения, так и содержаться в регистреобщего назначения. В'качестве значения смещения вы можете использовать результаты работы команд BSR и BSF. Все команды присваивают значение выбранного бита флагу CF.Команда проверки бита ВТ (Bit Test) переносит значение бита в флаг CF:bt операнд,смещение_битаНапример,,bt a x , 5;проверить значение бита 5jnc ml;переход, если бит = 0Команда проверки и установки бита BTS (Bit Test and Set) переносит значениебита в флаг CF и затем устанавливает проверяемый бит в 1:bts операнд,смещение_битаНапример,mov ax,10bts pole,ах ;проверить и установить 10-й бит в polejc ml;переход, если проверяемый бит был равен 1Команда проверки и сброса бита BTR (Bit Test and Reset) переносит значениебита во флаг CF и затем устанавливает этот бит в 0:btr операнд,смещение_битаКоманды сдвига199Команда проверки и инвертирования бита ВТС (Bit Test and Convert) переноситзначение бита в флаг CF и затем инвертирует значение этого бита:btc операнд,смещение_битаКоманды сдвигаКоманды сдвига также обеспечивают манипуляции над отдельными битами операндов, но иным способом, чем рассмотренные ранее логические команды.
Все команды сдвига перемещают биты в поле операнда влево или вправо, в зависимостиот кода операции. Все команды сдвига имеют одинаковую структуру:коп о п е р а н д , с ч е т ч и к _ с д в и г о вКоличество сдвигаемых разрядов (значение счетчик_сдвигов) может задаватьсядвумя способами:II статически — непосредственно во втором операнде;ii динамически — в регистре CL перед выполнением команды сдвига.Исходя из размерности регистра CL, понятно, что значение счетчик_сдвигов может лежать в диапазоне от 0 до 255. Но на самом деле это не совсем так.
В целяхоптимизации процессор воспринимает только значения пяти младших битов счетчика, то есть значение лежит в диапазоне от 0 до 31. В последних моделях процессора есть дополнительные команды, позволяющие делать 64-разрядные сдвиги. Мыих рассмотрим чуть позже.Все команды сдвига устанавливают флаг переноса CF. По мере сдвига битов запределы операнда они сначала попадают во флаг переноса CF, устанавливая егоравным значению очередного бита, оказавшегося за пределами операнда. Куда этотбит попадет дальше, зависит от типа команды сдвига и алгоритма программы.По принципу действия команды сдвига можно разделить на два типа:il команды линейного сдвига;к команды циклического сдвига.Линейный сдвигК командам линейного сдвига относятся команды, осуществляющие сдвиг по следующему алгоритму.1. Очередной «выдвигаемый» бит устанавливает флаг CF.2.
Бит, появляющийся с другого конца операнда, имеет значение 0.3. При сдвиге очередного бита он переходит во флаг CF, при этом значение предыдущего сдвинутого бита теряется]Команды линейного сдвига делятся на два подтипа:ti команды логического линейного сдвига;ш команды арифметического линейного сдвига.Далее перечислены команды логического линейного сдвига:ч& shl операнд,счетчик_сдвигов — логический сдвиг влево (Shift Logical Left).
Содержимое операнда сдвигается влево на количество битов, определяемое значением счетчик_сдвигов. Справа в позицию младшего бита вписываются нули.200Глава 9. Логические команды и команды сдвигаii shr операнд,счетчик_сдвигов — логический сдвиг вправо (Shift Logical Right).Содержимое операнда сдвигается вправо на количество битов, определяемоезначением счетчик_сдвигов. Слева в позицию старшего (знакового) бита вписываются нули.Рисунок 9.2 иллюстрирует принцип работы этих команд.Сдвиг влево логический shl^7VУ65V4УVУ321VV21ч^.0чФлаг cfСдвиг вправо логический shr/^.«7V6VV54V3*~10Флаг cfРис.