Команды SHLD, SHRD введены в систему команд микропроцессора 80386. Предназначены для сдвигов двух 16-битных или двух 32-битных операндов. Форматы команд:
SHLD, SHRD reg/ mem 16, reg, imn
SHLD, SHRD reg/ mem 32, reg, imn, где
imn - непосредственное значение, которое определяет число сдвигов.
Внутри процессора два первых операнда объединяются в промежуточном регистре двойной длины, код которого сдвигается. После сдвига результат в приемнике, а источник не изменяется.
2.5.3.5.Команды работы с двоичными цепочками
Команды работы с двоичными цепочками введены в систему команд микропроцессора 80386 включают две группы :
1) Команда поиска бита ВТ выбирает бит в двоичной цепочке и передает его значение в CF. BTC- поиск и инвертирование бита в цепочке, BTS- поиск и установка бита, BTR- поиск и сброс бита. Форматы команд этой группы одинаковые, поэтому приведены только для команды BT:
BT приемник (двоичная цепочка), источник (номер бита в цепочке)
BT
2) Команды сканирования битов
BSF- вперед
BSR- назад
}
предназначены для поиска в слове или двойном слове позиции первого единичного бита
Формат команд :
BSF,BSR приемник, источник
BSF,BSR
Приемник- номер первого единичного разряда.
Источник- битовая цепочка.
Результат исполнения команды фиксирует флаг ZF: ZF=0, если есть 1, и ZF=1, если источник равен 0 ( в этом случае приемник не определен).
2.5.4.Команды передачи управления.
2.5.4.1.Команды безусловной передачи управления.
К командам настоящей группы относятся команды переходов, вызовов (процедур) и возвратов (из процедур). Переходы загружают значение в указатель команды IP, нарушая тем самым последовательное выполнение команд. Вызовы выполняют то же самое, но в начале они запоминают текущее значение содержимого указателя IP в стеке, так что при возврате можно было возобновить выполнение программы с этой точки.
Переходы, вызовы и возвраты бывают двух видов - внутрисегментные и межсегментные. Первые из них передают управление внутри текущего сегмента кода, вторые - в произвольный сегмент кода (изменяя содержимое регистра CS), который становится текущим сегментом кода. Межсегментный вызов сохраняет в стеке текущее содержимое регистров CS и IP. Межсегментный возврат соответственно восстанавливает из стека содержимое регистров CS и IP. В случае внутрисегментного вызова и возврата в стеке сохраняется и восстанавливается только указатель команды IP. Отметим, что все вызовы одной и той же процедуры должны быть либо внутрисегментными либо межсегментными, так как при возврате из процедуры должно извлекаться из стека столько байт, сколько было включено в стек при вызове.
Команда CALL осуществляет вызов (межсегментный и внутрисегментный) а команда RET соответствующий ей возврат. Для того чтобы сообщить ассемблеру, какие типы вызовов и возвратов генерировать для процедуры, последнюю ограничивают операторами PROC и ENDP.
Например:
UPCOUNT PROC NEAR (FAR)
ADD CX, 1
RET
UPCOUNT ENDP
Так как процедура объявлена как NEAR, то вызов и возврат будут внутрисегментными, если бы мы объявили её как FAR, то вызов и возврат были бы межсегментными, и команда CALL загрузила бы в стек сначала содержимое регистра CS, а затем IP.
Команда JMP осуществляет внутрисегментные и межсегментные переходы. Для того чтобы указать, какой переход осуществить, необходимо указать тип метки перехода (NEAR или FAR). При внутрисегментном переходе команда JMP занимает 3 байта, а при межсегментном - 5 байт. Существует разновидность команды JMP для коротких внутрисегментных переходов (-128 +127 байт от адреса команды JMP). Она занимает в памяти 2 байта. Для определения такой команды следует указать, что её операнд имеет тип SHORT. Например, JMP SHORT LABEL1.
До сих пор мы рассматривали только прямые переходы и вызовы. Однако команды JMP и CALL могут осуществлять и косвенный переход или вызов через регистр или ячейку памяти. Если для косвенной передачи управления используется регистр, то в нём должно быть смещение процедуры или метки перехода относительно регистра CS (регистра кодов). Если для косвенной передачи управления используется ячейка памяти, то микропроцессор 8086 (80286) по умолчанию будет считать, что она содержится в сегменте DS (если не указан префикс смены сегмента или не используется регистр BP для адресации ячейки); если используется BP - то микропроцессор будет считать, что ячейка памяти находится в сегменте стека и адресуется регистром SS.
Примеры команд безусловной передачи управления приведены в таблицах 2.12 и 2.13.
Таблица 2.12. Примеры внутрисегментых команд передачи управления.
Внутрисегментные
Прямые
Косвенные
JMP LABEL
JMP MEMLOC
CALL LABEL
JMP BX
RET
CALL WORD PTR MEMLOC
RET 6
CALL CX
CALL WORD PRT ES: MEMLOC
Таблица 2.13. Примеры межсегментных команд передачи управления.
Прямые
Косвенные
JMP LABEL
JMP DWORD PTR MEMLOC
CALL LABEL
JMP DWORD PTR [BP]
RET
JMP DWORD PTR CS:[BX]
RET 6
CALL MEMLOC
CALL DWORD PTR SS: MEMLOC
Тип перехода или вызова при косвенных передачах через ячейку памяти определяется по типу объявленной переменной (WORD или DWORD) или явно в команде посредством операции WORD PTR или DWORD PTR. Возврат не может быть косвенным, так как управление всегда возвращается в место вызова, однако существует разновидность возврата, которая после восстановления значений содержимого регистра IP, прибавляет к значению указателя стека константу, содержащуюся в команде как непосредственный операнд. В результате из стека извлекаются и уничтожаются дополнительные элементы (то есть, например, параметры, переданные процедуре). Удобнее, чем чистить стек командой INC SP после возврата из процедуры, так как при многократных вызовах процедуры это надо будет делать каждый раз.
2.5.4.2. Команды условных переходов.
Команды условных переходов вместе с командой CMP реализуют передачу управления в зависимости от отношения между двумя числами. Сначала процессор выполняет команду сравнения и устанавливает по результату флаги, а затем выполняет команду условного перехода, которая проверяет флаги и производит переход, если числа удовлетворяют заданному отношению. Числа могут проверяться на равенство или требуется узнать, какое из них больше или меньше. Какое число больше 11111111 или 00000000? Если число без знака, то первое = 255, а второе = 0 и первое больше второго. Если число со знаком, то первое = (-1) и меньше второго. Следовательно, отношения “меньше” или “больше” зависят от того, знаковые или беззнаковые числа. Поэтому целесообразно ввести новые термины, позволяющие различать эти два случая. При сравнении знаковых чисел пользуемся терминами “больше” и “меньше”, а при сравнении беззнаковых чисел терминами “выше” и “ниже” (так как беззнаковые числа обычно используются для сравнения адресов). Каждое из условий можно определить по состояниям флагов, поэтому в микропроцессоре есть команды, ориентированные на проверку отношений и команды, ориентированные на проверку состояния флагов. Перечень команд условных переходов приведен в таблице 2.14.
Таблица 2.14. Перечень команд условных переходов.
Команда
Описание
Состояние флагов
JE / JZ
Перейти, если равно / если ноль
ZF = 1
JNE / JNZ
Перейти, если не равно / если не ноль
ZF = 0
JL / JNGE
Перейти, если меньше / если не больше и не равно
SF ¹ OF
JNL / JGE
Перейти, если не меньше / если больше или равно
SF = OF
JG / JNLE
Перейти, если больше / если не меньше и не равно
ZF = 0 & SF = OF
JNG / JLE
Перейти, если не больше / если меньше или равно
ZF = 1 & SF ¹ OF
JB / JNAE
Перейти, если ниже / если не выше и не равно
CF = 1
JNB / JAE
Перейти, если не ниже / если выше или равно
CF = 0
JA / JNBE
Перейти, если выше / если не ниже и не равно
CF = 0 & ZF = 0
JNA / JBE
Перейти, если не выше / если выше или равно
CF = 1 & ZF = 1
JC / JNC
Перейти, если есть перенос / если переноса нет
CF = 1 / CF = 0
JS / JNS
Перейти, если есть знак / если нет знака
SF = 1 / SF = 0
JO / JNO
Перейти, если переполнение / если не переполнение
OF = 1 / OF = 0
JP / JNE
Перейти, если есть паритет / если паритет четный
PF = 1
JNP / JPO
Перейти, если паритета нет / если паритет нечетный
PF = 0
JCXZ
Перейти, если CX = 0
CX = 0
JECXZ
Перейти, если ECX = 0
CX = 0
Команды условного перехода могут использоваться не только с командой CMP, но и с любой другой командой, воздействующей на флаги. Каждая из команд условного перехода в 80286 состоит из 8-битного кода операции и 8-бит, определяющих место перехода (то есть имеет размер 2 байта). 8 бит определяют относительное смещение места перехода и команды условного перехода, то есть в диапазоне -128 +127 байт от команды. “Близкий” или “далёкий” условный переход всегда можно сделать при помощи двух команд: “короткого” условного перехода и “близкого” или “далёкого” безусловного перехода. В микропроцессоре 80386 команды условного перехода могут быть с типом NEAR.