48552 (588566), страница 10
Текст из файла (страница 10)
mov AX,00101001b
mov BX,11110111b
xor ax,bx; 11011110b
Пример 3
mov SI,0AAAAh
mov BX,5555h
xor SI,BX ; SI=FFFFh,BX=5555h
Пример 4
хог ВХ, ВХ ; Обнуление ВХ
Команда TEST.
Команда TEST (Логическое сравнение) выполняет операцию логического умножения И над двумя операндами и, в зависимости от результата, устанавливает флаги SF, ZF и PF. Флаги OF и CF сбрасываются, a AF имеет неопределенное значение. Состояние флагов можно затем проанализировать командами условных переходов. Команда TEST не изменяет ни один из операндов.
В качестве первого операнда команды TEST можно указывать регистр (кроме сегментного) или ячейку памяти, в качестве второго - регистр (кроме сегментного), ячейку памяти или непосредственное значение, однако не допускается определять оба операнда одновременно как ячейки памяти. Операнды могут быть байтами или словами и представлять числа со знаком или без знака.
Правила побитового умножения:
Первый операнд-бит 0101 | Бит результата 0001 |
Второй операнд-бит 0011 |
Флаг SF устанавливается в 1, если в результате выполнения команды образовалось число с установленным знаковым битом.
Флаг ZF устанавливается в 1, если в результате выполнения команды образовалось число, состоящее из одних двоичных нулей.
Флаг PF устанавливается в 1, если в результате выполнения команды образовалось число с четным количеством двоичных единиц в его битах.
Пример 1
test AX,1
jne label2: ; Переход, если бит 0 в АХ установлен
je label1: ; Переход, если бит 0 в АХ сброшен
Пример №1.4.1.1
. model tiny | ; модель памяти в которой сегменты кода, данных и стека объединены. |
. code | ; сегмент кода, который содержит данные. |
org 100h | ; начало СОМ-файла |
begin: | ; метка начала кода программы |
mov СX, | ; загружаем в CX число1 |
mov BX, | ; загружаем в BX число2 |
test cx,bx | ; логически сравниваем числа в регистрах cx с bx |
jne label2 | ; если одно из значений не равно 0 то переходим на метку label2 |
je label1 | ; если одно из значений равно 0 то переходим на метку label1 |
ret | ; функция DOS "завершить программу" (не выполняется) |
label1: | ; начало блока метки Label1 |
mov ah,9 | ; помещаем номер функции DOS "вывод строки (9)" в регистр АН. |
mov dx,offset string | помещает в регистр DX смещение метки String относительно начала сегмента данных |
int 21h | ; функция DOS "вывод строки" |
ret | ; функция DOS "завершить программу" |
String db 'одно из чисел равно 0$' | ; cтрока с содержащая выводимые данные. |
label2: | ; начало блока метки Label2 |
mov ah,9 | ; помещаем номер функции DOS "вывод строки (9)" в регистр АН. |
mov dx,offset string1 | помещает в регистр DX смещение метки String1 относительно начала сегмента данных |
int 21h | ; функция DOS "вывод строки" |
ret | ; функция DOS "завершить программу" |
string1 db 'не равны 0$' | ; cтрока с содержащая выводимые данные. |
end begin | ; метка окончания кода программы |
Данный пример сравнивает два значения (строка (6)), если одно из двух значений равно нулю тогда переходим на метку label1 (строка (10)) далее выполняются команды, следующие после этой метки, в случае если одно из двух значений равно нулю тогда переходим на метку label2
Пример 2
test SI,8
jne bityes ; Переход, если бит 3 в SI установлен
je bitno ; Переход, если бит 0 в АХ сброшен
Пример 3
test DX,0FFFFh
jz null ; Переход, если DX=0
jnz smth; Переход, если DX не 0
Команда NOT.
Команда NOT (NOT Инверсия, дополнение до 1, логическое отрицание) выполняет инверсию битов указанного операнда, заменяя 0 на 1 и наоборот. В качестве операнда можно указывать регистр (кроме сегментного) или ячейку памяти размером как в байт, так и в слово. Не допускается использовать в качестве операнда непосредственное значение. Команда не воздействует на флаги процессора.
Правила побитовой инверсии:
Операнд-бит 0 1 | Бит результата 1 0 |
Пример 1
mov AX,0FFFFh
not AX; AX=0000h
Пример 2
mov SI,5551h
not SI; SI=AAAEh
Характерные примеры работы команд логических операций.
Для следующих несвязанных примеров, предположим, что:
AL содержит 1100 0101
BH содержит 0101 1100:
1. AND AL,BH; Устанавливает в AL 0100 0100
2. OR BH,AL; Устанавливает в BH 1101 1101
3. XOR AL,AL; Устанавливает в AL 0000 0000
4. AND AL,00; Устанавливает в AL 0000 0000
5. AND AL,0FH; Устанавливает в AL 0000 0101
6. OR CL,CL; Устанавливает флаги SF и ZF
Примеры 3 и 4 демонстрируют способ очистки регистра.
В примере 5 обнуляются левые четыре бита регистра AL.
Можно применить команду OR для следующих целей:
1. OR CX,CX; Проверка CX на нуль
JZ; Переход, если нуль
2. OR CX,CX; Проверка знака в CX
JS; Переход, если отрицательно
3. Задание для выполнения.
Запустить эмулятор EMU8086.
Пользуясь правилами оформления ассемблерных программ, наберите код примера №1.4.1.1, запустите код на выполнение.
Проанализируйте работу кода примера №1.4.1.1
С помощью справки эмулятора EMU8086 выясните работу команд (jne, je, js, jz)
Получите задание у преподавателя (один из четырех вариантов (команды (and, or, xor, test, not))) и, пользуясь правилами оформления ассемблерных программ, напишите три программы характеризующие (показывающие) работу их с числами (двоичной, десятеричной, шестнадцатеричной систем счисления) согласно перечислению приведенных примеров.
Результаты работы продемонстрируйте преподавателю.
4. Контрольные вопросы
4.1 Назначение команд логических операций?
4.2 Команда and основное назначение?
4.3 Команда or основное назначение?
4.4 Команда xor основное назначение?
4.5 Команда test основное назначение?
4.6 Команда not основное назначение?
4.7 Альтернативная работа команд (test, xor, and)?
4.8 Допустим что будит
4.9 В чем заключается работа связки команд jne, je?
4.10 В чем заключается работа связки команд js, jz?
4.11 Что произойдет, если в примере №1.4.1.1 мы изменим строку (8) на следующую (jne label1)?
ЛАБОРАТОРНАЯ РАБОТА №8
ОЗНАКОМЛЕНИЕ С РАБОТОЙ ЦИКЛОВ
Цель работы: ознакомиться со структурой и реализацией циклов в программе.
Краткие теоретические сведения.
Циклы, позволяющие выполнить некоторый участок программы многократно, в любом языке являются одной из наиболее употребительных конструкций. В системе команд МП 86 циклы реализуются, главным образом, с помощью команды loop (петля), хотя имеются и другие способы организации циклов. В большинстве случаях число шагов в цикле определяется содержимым регистра СХ, поэтому максимальное число шагов составляет 64 К.
Организация циклических переходов, как на языках высокого уровня, так и на языке assembler представляет собой замечательное средство, позволяющее значительно снизить код исполняемой программы.
В общем виде любой цикл записывается в ассемблере как условный переход.
Организация цикла с помощью команды LOOP (Первый способ).
Команда loop (анг. петля) выполняет декремент содержимого регистра СХ (счетчик), и если оно не равно 0, осуществляет переход на указанную метку вперед или назад в том же программном сегменте в диапазоне - 128... + 127 байт. Обычно метка помещается перед первым предложением тела цикла, а команда loop является последней командой цикла. Содержимое регистра СХ рассматривается как целое число без знака, поэтому максимальное число повторений группы включенных в цикл команд составляет 65536 (если перед входом в цикл СХ=0). Команда не воздействует на флаги процессора.
Команда | Назначение | Процессор |
LOOP метка | Организация циклов | 8086 |
Простейший пример организации циклического перехода (со счетчиком в регистре cx) на языке Assembler:
. model tiny | ; модель памяти, в которой сегменты кода, данных и стека объединены. |
. code | ; сегмент кода, который содержит и данные. |
org 100h | ; начало СОМ-файла |
begin: | ; метка начала кода программы |
mov cx,10 | ; загружаем в (регистр-счетчик) CX количество повторов (отсчет будет идти от 10 до 0) |
Label1: | ; создаем метку (Label - метка). |
mov ah,9 | ; помещаем номер функции DOS "вывод строки (9)" в регистр АН. |
mov dx,offset String | помещает в регистр DX смещение метки String относительно начала сегмента данных |
int 21h | ; функция DOS "вывод строки" |
loop Label1 | ; оператор loop уменьшает на единицу CX и, если он не равен нулю, переходит на метку Label1 (строка 6) |
ret | ; функция DOS "завершить программу" |
string db 'privet $' | ; cтрока с содержащая выводимые данные. |
end begin | ; метка окончания кода программы |
В строке (5) загружаем в CX количество повторов (отсчет будет идти от 10 до 0). В строке (6) создаем метку (Label - метка). Далее (строки (7) - (9)) выводим сообщение. И в строке (10) оператор loop уменьшает на единицу CX и, если он не равен нулю, переходит на метку Label1 (строка (6)). Таким образом, строка будет выведена на экран десять раз. Когда программа перейдет на строку (11), регистр CX будет равен нулю.
Организация цикла с помощью команды JMP (Второй способ).
Команда jmp передает управление в указанную точку того же или другого программного сегмента. Адрес возврата не сохраняется. Команда не воздействует на флаги процессора.
Команда jmp имеет пять разновидностей:
переход прямой короткий (в пределах - 128... + 127 байтов);