salоперанд,счетчик_сдвигов (ShiftArithmeticLeft)
sarоперанд,счетчик_сдвигов
арифметический сдвиг влево/вправо. Содержимое операнда сдвигается влево/ вправо на количество битов, определяемое значением счетчик_сдвигов. Справа/ Слева в операнд вписываются нули.
Команда sal не сохраняет знака, но устанавливает флаг cf в случае смены знака очередным выдвигаемым битом. В остальном команда sal полностью аналогична команде shl;
Команда sar сохраняет знак, восстанавливая его после сдвига каждого очередного бита.
rolоперанд,счетчик_сдвигов(Rotate Left) — циклическийсдвигвлево.
Содержимое операнда сдвигается влево на количество бит, определяемое операндом счетчик_сдвигов. Сдвигаемые влево биты записываются в тот же операнд справа.
rorоперанд,счетчик_сдвигов (Rotate Right) — циклический сдвиг вправо.
Как видно из рис., команды простого циклического сдвига в процессе своей работы осуществляют одно полезное действие, а именно: циклически сдвигаемый бит не только вдвигается в операнд с другого конца, но и одновременно его значение становиться значением флага cf.
Команды циклического сдвига через флаг переноса cf отличаются от команд простого циклического сдвига тем, что сдвигаемый бит не сразу попадает в операнд с другого его конца, а записывается сначала в флаг переноса cf. Лишь следующее исполнение данной команды сдвига (при условии, что она выполняется в цикле) приводит к помещению выдвинутого ранее бита с другого конца операнда (см. рис. 4).
rclоперанд,счетчик_сдвигов (Rotate through Carry Left) — циклический сдвиг влево через перенос.
Содержимое операнда сдвигается влево на количество бит, определяемое операндом счетчик_сдвигов. Сдвигаемые биты поочередно становятся значением флага переноса cf.
rcrоперанд,счетчик_сдвигов (Rotate through Carry Right) — циклический сдвиг вправо через перенос.
Содержимое операнда сдвигается вправо на количество бит, определяемое операндом счетчик_сдвигов. Сдвигаемые биты поочередно становятся значением флага переноса cf.
Из рис. 4 видно, что при сдвиге через флаг переноса появляется промежуточный элемент, с помощью которого, в частности, можно производить подмену циклически сдвигаемых битов, в частности, рассогласование битовых последовательностей.
Под рассогласованием битовой последовательности здесь и далее подразумевается действие, которое позволяет некоторым образом локализовать и извлечь нужные участки этой последовательности и записать их в другое место
Пример. Дано отрицательное число. Выведите на экран его значение по модулю деленное на 2.
Любое отрицательное число хранится в дополнительном формате
-1 ffh
-2 feh
…
-10 f6h
получить значение числа по модулю, можно осуществив логическое отрицание над числом и добавив 1.
model small
.stack 100h
.data
x db -12
.code
start:
mov ax,@data
mov ds,ax
moval,x ;в al отрицательное число
notal
incal ;число по модулю
shral,1
;выводим результат на экран
aam ;
;преобразование двоичного числа меньшего 63h (9910), которое находится в al в его ;неупакованный BCD-эквивалент
; -разделить значение регистра al на 10;
; -записать частное в регистр ah, остаток — в регистр al.
movdx,ax ;число в регистр dx
ordx,3030h ;получаю ASCII код числа
xchgdh,dl ;меняю местами старший и младший байт, для вывода символа из dl
movah,02h ;
int 21h ;вывожу старшую половинку числа
xchgdh,dl ;меняю местами старший и младший байт,
int 21h ;вывожу младшую половинку числа
mov ax,4c00h
int 21h
end start
Команды передачи управления
По принципу действия, команды микропроцессора, обеспечивающие организацию переходов в программе, можно разделить на три группы:
1. Команды безусловной передачи управления:
- команда безусловного перехода; jmp
- вызова процедуры и возврата из процедуры; call, ret
- вызова программных прерываний и возврата из программных прерываний. Int, iret
2. Команды условной передачи управления:
- команды перехода по результату команды сравнения cmp;
- команды перехода по состоянию определенного флага;
- команды перехода по содержимому регистра ecx/cx.
3. Команды управления циклом:
- команда организации цикла со счетчиком ecx/cx;
- команда организации цикла со счетчиком ecx/cx с возможностью досрочного выхода из цикла по дополнительному условию.
jmp адрес_перехода - безусловный переход без сохранения информации о точке возврата. Аналог goto.
jmpm1 m4:
… …
m1: jmpm4
Команды условного перехода имеют одинаковый синтаксис:
jcc метка_перехода
Мнемокод всех команд начинается с “j” — от слова jump (прыжок), cc — определяет конкретное условие, анализируемое командой. Что касается операнда метка_перехода, то эта метка может находится только в пределах текущего сегмента кода, межсегментная передача управления в условных переходах не допускается.
Для того чтобы принять решение о том, куда будет передано управление командой условного перехода, предварительно должно быть сформировано условие, на основании которого и будет приниматься решение о передаче управления. Источниками такого условия могут быть:
- любая команда, изменяющая состояние арифметических флагов;
- команда сравнения cmp, сравнивающая значения двух операндов;
- состояние регистра ecx/cx.
Условные переходы по содержимому флагов
Название флага | Номер бита в eflags/flag | Команда условного перехода | Значение флага для осуществления перехода |
Флаг переноса cf | 1 | jc | cf = 1 |
Флаг четности pf | 2 | jp | pf = 1 |
Флаг нуля zf | 6 | jz | zf = 1 |
Флаг знака sf | 7 | js | sf = 1 |
Флаг переполнения of | 11 | jo | of = 1 |
Флаг переноса cf | 1 | jnc | cf = 0 |
Флаг четности pf | 2 | jnp | pf = 0 |
Флаг нуля zf | 6 | jnz | zf = 0 |
Флаг знака sf | 7 | jns | sf = 0 |
Флаг переполнения of | 11 | jno | of = 0 |
jcxz метка_перехода (Jump if cx is Zero) — переход, если cx ноль;
jecxzметка_перехода (JumpEqualecxZero) — переход, если ecxноль.
Пример программы: определите, равны ли два числа вводимые пользователем с клавиатуры.
model small
.stack 100h
.data
s1 db 'числаравны$'
s2 db 'числа не равны$'
.code
start:
mov ax,@data
movds,ax
movah,01h
int 21h ;ввели первое число
mov dl,al
mov ah,01h
int 21h ;ввели второе число
subal,dl ;сравнили числа
jnz m1
mov dx, offset s1
jmp m2
m1: mov dx, offset s2
m2: movah,09h
int 21h ;выводим информационную строку
movax,4c00h
int 21h
end start
Команда сравнения cmp
cmp операнд_1,операнд_2 - сравнивает два операнда и по результатам сравнения устанавливает флаги. Команда сравнения cmp имеет интересный принцип работы. Он абсолютно такой же, как и у команды вычитания sub. Единственное, чего она не делает — это запись результата вычитания на место первого операнда.
Алгоритм работы:
-выполнить вычитание (операнд1-операнд2);
-в зависимости от результата установить флаги, операнд1 и операнд2 не изменять (то есть результат не запоминать).
Условные переходы после команд сравнения
Типы операндов | Мнемокод команды условного перехода | Критерий условного перехода | Значения флагов для осществления перехода |
Любые | je | операнд_1 = операнд_2 | zf = 1 |
Любые | jne | операнд_1<>операнд_2 | zf = 0 |
Со знаком | jl/jnge | операнд_1 < операнд_2 | sf <> of |
Со знаком | jle/jng | операнд_1 <= операнд_2 | sf <> of or zf = 1 |
Со знаком | jg/jnle | операнд_1 > операнд_2 | sf = of and zf = 0 |
Со знаком | jge/jnl | операнд_1 => операнд_2 | sf = of |
Без знака | jb/jnae | операнд_1 < операнд_2 | cf = 1 |
Без знака | jbe/jna | операнд_1 <= операнд_2 | cf = 1 or zf=1 |
Без знака | ja/jnbe | операнд_1 > операнд_2 | cf = 0 and zf = 0 |
Без знака | jae/jnb | операнд_1 => операнд_2 | cf = 0 |
Пример программы: определите, равны ли два числа вводимые пользователем с клавиатуры.
model small
.stack 100h
.data
s1 db 'числаравны$'
s2 db 'числа не равны$'
.code
start:
mov ax,@data
movds,ax
movah,01h
int 21h ;ввели первое число
mov dl,al
mov ah,01h
int 21h ;ввели второе число
cmpal,dl ;сравнили числа
jne m1
mov dx, offset s1
jmp m2
m1: mov dx, offset s2
m2: movah,09h
int 21h ;выводим информационную строку
movax,4c00h
int 21h
loop метка_перехода (Loop) — повторить цикл
Работа команды заключается в выполнении следующих действий:
- декремента регистра ecx/cx;
- сравнения регистра ecx/cx с нулем:
- если (ecx/cx) > 0, то управление передается на метку перехода;
- если (ecx/cx) = 0, то управление передается на следующую после loop команду
movcx, количество циклов
м1: тело цикла
loopm1
loope/loopz метка_перехода (Loop till cx <> 0 or Zero Flag = 0) — повторить цикл, пока cx <> 0 или zf = 0.
loopne/loopnz метка_перехода (Loop till cx <> 0 or Not Zero flag=0) — повторить цикл пока cx <> 0 или zf = 1
Недостаток команд организации цикла loop, loope/loopz и loopne/loopnz в том, что они реализуют только короткие переходы (от –128 до +127 байт).
Организация вложенных циклов
movcх,n ; в сх заносим количество итераций внешнего цикла