Команда:
|
SAR приемник, счетчик
|
Назначение:
|
Арифметический сдвиг вправо
|
Команда:
|
SAL приемник, счетчик
|
Назначение:
|
Арифметический сдвиг влево
|
Команда:
|
SHR приемник, счетчик
|
Назначение:
|
Логический сдвиг вправо
|
Команда:
|
SHL приемник, счетчик
|
Назначение:
|
Логический сдвиг влево
|
Процессор:
|
8086
|
Рис. 7. Сдвиговые операции
Команда:
|
SHRD приемник, источник, счетчик
|
Назначение:
|
Сдвиг повышенной точности вправо
|
Команда:
|
SHLD приемник, источник, счетчик
|
Назначение:
|
Сдвиг повышенной точности влево
|
Процессор:
|
80386
|
Рис. 8. Сдвиги двойной точности
Команда:
|
ROR приемник, счетчик
|
Назначение:
|
Циклический сдвиг вправо
|
Команда:
|
ROL приемник, счетчик
|
Назначение:
|
Циклический сдвиг влево
|
Команда:
|
RCR приемник, счетчик
|
Назначение:
|
Циклический сдвиг вправо через флаг переноса
|
Команда:
|
RCL приемник, счетчик
|
Назначение:
|
Циклический сдвиг влево через флаг переноса
|
Процессор:
|
8086
|
Рис. 9. Циклические сдвиги
Команды передачи управления
Команда:
|
JMP операнд
|
Назначение:
|
Безусловный переход
|
Процессор:
|
8086
|
В зависимости от типа перехода различают:
-
переход типа short (короткий переход) — если адрес перехода находится в пределах от –127 до +128 байт от команды JMP;
-
переход типа near (ближний переход) — если адрес перехода находится в том же сегменте памяти, что и команда JMP;
-
переход типа far (дальний переход) — если адрес перехода находится в другом сегменте. Дальний переход может выполняться и в тот же самый сегмент, если в сегментной части операнда указано число, совпадающее с текущим значением CS;
-
переход с переключением задачи — передача управления другой задаче в многозадачной среде. Этот вариант будет рассмотрен в главе, посвященной защищенному режиму.
Команда:
|
Jcc метка
|
Назначение:
|
Условный переход
|
Процессор:
|
8086
|
Таблица 7. Варианты команды Jcc
Код команды
|
Реальное условие
|
Условие для CMP
|
JA
JNBE
|
CF = 0 и ZF = 0
|
если выше
если не ниже или равно
|
JAE
JNB
JNC
|
CF = 0
|
если выше или равно
если не ниже
если нет переноса
|
JB
JNAE
JC
|
CF = 1
|
если ниже
если не выше или равно
если перенос
|
JBE
JNA
|
CF = 1 и ZF = 1
|
если ниже или равно
если не выше
|
JE
JZ
|
ZF = 1
|
если равно
если ноль
|
JG
JNLE
|
ZF = 0 и SF = OF
|
если больше
если не меньше или равно
|
JGE
JNL
|
SF = OF
|
если больше или равно
если не меньше
|
JL
JNGE
|
SF <> OF
|
если меньше
если не больше или равно
|
JLE
JNG
|
ZF = 1 и SF <> OF
|
если меньше или равно
если не больше
|
JNE
JNZ
|
ZF = 0
|
если не равно
если не ноль
|
JNO
|
OF = 0
|
если нет переполнения
|
JO
|
OF = 1
|
если есть переполнение
|
JNP
JPO
|
PF = 0
|
если нет четности
если нечетное
|
JP
JPE
|
PF = 1
|
если есть четность
если четное
|
JNS
|
SF = 0
|
если нет знака
|
JS
|
SF = 1
|
если есть знак
|
Команда:
|
JCXZ метка
|
Назначение:
|
Переход, если СХ = 0
|
Процессор:
|
8086
|
|
|
Команда:
|
JECXZ метка
|
Назначение:
|
Переход, если EСХ = 0
|
Процессор:
|
80386
|
Команда:
|
LOOP метка
|
Назначение:
|
Цикл
|
Процессор:
|
8086
|
Команда:
|
LOOPE метка
|
Назначение:
|
Цикл, пока равно
|
Команда:
|
LOOPZ метка
|
Назначение:
|
Цикл, пока ноль
|
Команда:
|
LOOPNE метка
|
Назначение:
|
Цикл, пока не равно
|
Команда:
|
LOOPNZ метка
|
Назначение:
|
Цикл, пока не ноль
|
Процессор:
|
8086
|
Команда:
|
CALL операнд
|
Назначение:
|
Вызов процедуры
|
Процессор:
|
8086
|
Команда:
|
RET число
RETN число
RETF число
|
Назначение:
|
Возврат из процедуры
|
Процессор:
|
8086
|
Команда:
|
INT число
|
Назначение:
|
Вызов прерывания
|
Процессор:
|
8086
|
Команда:
|
IRET
IRETD
|
Назначение:
|
Возврат из обработчика прерывания
|
Процессор:
|
8086
|
Команда:
|
INT3
|
Назначение:
|
Вызов прерывания 3
|
Процессор:
|
8086
|
Команда:
|
INTO
|
Назначение:
|
Вызов прерывания 4 при переполнении
|
Процессор:
|
8086
|
Команда:
|
BOUND индекс, границы
|
Назначение:
|
Проверка выхода за границы массива
|
Процессор:
|
80186
|
Команда:
|
ENTER размер, уровень
|
Назначение:
|
Вход в процедуру
|
Процессор:
|
80186
|
Команда:
|
LEAVE
|
Назначение:
|
Выход из процедуры
|
Процессор:
|
80186
|
1.14 Микропроцессор Intel х86. Способы адресации: регистровая, непосредственная, прямая, косвенная.
Регистровая адресация
Операнды могут располагаться в любых регистрах общего назначения и сегментных регистрах. В этом случае в тексте программы указывается название соответствующего регистра, например команда, копирующая в регистр AX содержимое регистра BX, записывается как
mov ax,bx
Непосредственная адресация
Некоторые команды (все арифметические команды, кроме деления) позволяют указывать один из операндов непосредственно в тексте программы, например команда
mov ax,2
помещает в регистр AX число 2.
Прямая адресация
Если известен адрес операнда, располагающегося в памяти, можно использовать этот адрес. Если операнд — слово, находящееся в сегменте, на который указывает ES, со смещением от начала сегмента 0001, то команда
mov ax,es:0001
поместит это слово в регистр AX. В реальных программах обычно для задания статических переменных используют директивы определения данных, которые позволяют ссылаться на статические переменные не по адресу, а по имени. Тогда, если в сегменте, указанном в ES, была описана переменная word_var размером в слово, можно записать ту же команду как
mov ax,es:word_var
В таком случае ассемблер сам заменит слово «word_var» на соответствующий адрес. Если селектор сегмента данных находится в DS, имя сегментного регистра при прямой адресации можно не указывать, DS используется по умолчанию. Прямая адресация иногда называется адресацией по смещению.
Адресация отличается для реального и защищенного режимов. В реальном режиме (так же как и в режиме V86) смещение всегда 16-битное, это значит, что ни непосредственно указанное смещение, ни результат сложения содержимого разных регистров в более сложных методах адресации не могут превышать границ слова. При программировании для Windows, для DOS4G, PMODE и в других ситуациях, когда программа будет запускаться в защищенном режиме, смещение не может превышать границ двойного слова.
Косвенная адресация
По аналогии с регистровыми и непосредственными операндами адрес операнда в памяти также можно не указывать непосредственно, а хранить в любом регистре. До 80386 для этого можно было использовать только BX, SI, DI и BP, но потом эти ограничения были сняты и адрес операнда разрешили считывать также и из EAX, EBX, ECX, EDX, ESI, EDI, EBP и ESP (но не из AX, CX, DX или SP напрямую — надо использовать EAX, ECX, EDX, ESP соответственно или предварительно скопировать смещение в BX, SI, DI или BP). Например, следующая команда помещает в регистр AX слово из ячейки памяти, селектор сегмента которой находится в DS, а смещение — в BX:
mov ax,[bx]
Как и в случае прямой адресации, DS используется по умолчанию, но не во всех случаях: если смещение берут из регистров ESP, EBP или BP, то в качестве сегментного регистра используется SS. В реальном режиме можно свободно пользоваться всеми 32-битными регистрами, надо только следить, чтобы их содержимое не превышало границ 16-битного слова.
Достарыңызбен бөлісу: |