Что такое mov ассемблер
ASSEMBLER&WIN32. КУРС МОЛОДОГО БОЙЦА. УРОК 3.mov — команда ассемблера
Posted by key under assembler
Основы Ассемблера
Когда вы пишете программу на ассемблере, вы просто пишете команды процессору. Команды процессору — это просто коды или коды операций или опкоды. Опкоды — фактически «читаемый текст»- версии шестнадцатеричных кодов. Из-за этого, ассемблер считается самым низкоуровневым языком программирования, все в ассемблере непосредственно преобразовывается в шестнадцатеричные коды. Другими словами, у вас нет компилятора, который преобразовывает язык высокого уровня в язык низкого уровня, ассемблер только преобразовывает коды ассемблера в данные.
В этом уроке мы обсудим несколько опкодов, которые имеют отношение к вычислению, поразрядным операциям, и т.д. Другие опкоды: команды перехода, сравнения и т.д, будут обсуждены позже.
Комментарии в ваших программах оставляются после точки с запятой. Точно также как в дельфи или си через //.
Числа в ассемблере могут представляться в двоичной, десятеричной или шестнадцатеричной системе. Для того, чтобы показать в какой системе использовано число надо поставить после числа букву. Для бинарной системы пишется буква b (пример: 0000010b, 001011010b), для десятеричной системы можно ничего не указывать после числа или указать букву d (примеры: 4589, 2356d), для шестнадцатеричной системы надо указывать букву h, шестнадцатеричное число надо обязательно писать с нулём в начале (примеры: 00889h, 0AC45h, 056Fh, неправильно F145Ch, С123h).
Самая первая команда будет хорошо всем известная MOV. Эта команда используется для копирования (не обращайте внимания на имя команды) значения из одного места в другое. Это ‘место’ может быть регистр, ячейка памяти или непосредственное значение (только как исходное значение). Синтаксис команды:
mov приемник, источник
Вы можете копировать значение из одного регистра в другой.
Вышеприведенная команда копирует содержание ecx в edx. Размер источника и приемника должны быть одинаковыми, например: эта команда — НЕ допустима:
mov al, ecx ; не правильно
Этот опкод пытается поместить DWORD (32-битное) значение в байт (8 битов). Это не может быть сделано mov командой (для этого есть другие команды).
А эти команды правильные, потому что у них источник и приемник не отличаются по размеру:
mov al, bl
mov cl, dl
mov cx, dx
mov ecx, ebx
Вы также можете получить значение из памяти и поместить эго в регистр. Для примера возьмем следующую схему памяти:
смещение | 34 | 35 | 36 | 37 | 38 | 39 | 3A | 3B | 3C | 3D | 3E | 3F | 40 | 41 | 42 |
данные | 0D | 0A | 50 | 32 | 44 | 57 | 25 | 7A | 5E | 72 | EF | 7D | FF | AD | C7 |
(Каждый блок представляет байт)
Значение смещения обозначено здесь как байт, но на самом деле это это — 32-разрядное значение. Возьмем для примера 3A, это также — 32-разрядное значение: 0000003Ah. Только, чтобы с экономить пространство, некоторые используют маленькие смещения.
Посмотрите на смещение 3A в таблице выше. Данные на этом смещении — 25, 7A, 5E, 72, EF, и т.д. Чтобы поместить значение со смещения 3A, например, в регистр, вы также используете команду mov:
dword (32-бит) значение 10203040 шестнадцатиричное сохраняется в памяти как: 40, 30, 20, 10
word (16-бит) значение 4050 шестнадцатиричное сохраняется в памяти как: 50, 40
Вернемся к примеру выше. Вы также можете это делать и с другими размерами:
mov cl, byte ptr [34h] ; cl получит значение 0Dh
mov dx, word ptr [3Eh] ; dx получит значение 7DEFh
Вы, наверное, уже поняли, что префикс ptr обозначает, что надо брать из памяти некоторый размер. А префикс перед ptr обозначает размер данных:
Byte — 1 байт
Word — 2 байта
Dword — 4 байта
Иногда размер можно не указывать:
mov eax, [00403045h]
Так как eax — 32-разрядный регистр, ассемблер понимает, что ему также требуется 32-разрядное значение, в данном случае из памяти со смещением 403045h.
Можно также непосредственные значения:
Эта команда просто запишет в регистр edx, значение 5006. Скобки, [ и ], используются, для получения значения из памяти (в скобках находится смещение), без скобок, это просто непосредственное значение.
Можно также использовать регистр как ячейку памяти (он должен быть 32-разрядным в 32-разрядных программах):
mov eax, 403045h ; пишет в eax значение 403045
mov cx, [eax] ; помещает в регистр CX значение (размера word) из памяти
; указанной в EAX (403045)
В mov cx, [eax], процессор сначала смотрит, какое значение (= ячейке памяти) содержит eax, затем какое значение находится в той ячейке памяти, и помещает это значение (word, 16 бит, потому что приемник, cx, является 16-разрядным регистром) в CX.
(1) mov ecx, 100
(2) mov eax, 200
(3) push ecx ; сохранение ecx
(4) push eax
(5) xor ecx, eax
(6) add ecx, 400
(7) mov edx, ecx
(8) pop ebx
(9) pop ecx
Анализ:
1: поместить 100 в ecx
2: поместить 200 в eax
3: разместить значение из ecx (=100) в стеке (размещается первым)
4: разместить значение из eax (=200) в стеке (размещается последним)
5/6/7: выполнение операций над ecx, значение в ecx изменяется
8: извлечение значения из стека в ebx: ebx станет 200 (последнее размещение, первое извлечение)
9: извлечение значения из стека в ecx: ecx снова станет 100 (первое размещение, последнее извлечение)
Чтобы узнать, что происходит в памяти, при размещении и извлечении значений в стеке, см. на рисунок ниже:
Смещение | 1203 | 1204 | 1205 | 1206 | 1207 | 1208 | 1209 | 120A | 120B |
Значение | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 |
ESP |
(стек здесь заполнен нулями, но в действительности это не так, как здесь). ESP стоит в том месте, на которое он указывает)
mov ax, 4560h
push ax
Смещение | 1203 | 1204 | 1205 | 1206 | 1207 | 1208 | 1209 | 120A | 120B |
Значение | 00 | 00 | 60 | 45 | 00 | 00 | 00 | 00 | 00 |
ESP |
mov cx, FFFFh
push cx
Смещение | 1203 | 1204 | 1205 | 1206 | 1207 | 1208 | 1209 | 120A | 120B |
Значение | FF | FF | 60 | 45 | 00 | 00 | 00 | 00 | 00 |
ESP |
Смещение | 1203 | 1204 | 1205 | 1206 | 1207 | 1208 | 1209 | 120A | 120B |
Значение | FF | FF | 60 | 45 | 00 | 00 | 00 | 00 | 00 |
ESP |
edx теперь 4560FFFFh.
Вызов подпрограмм возврат из них — CALL, RET. Команда call передает управление ближней или дальней процедуре с запоминанием в стеке адреса точки возврата. Команда ret возвращает управление из процедуры вызывающей программе, адрес возврата получает из стека. Пример:
..code..
call 0455659
..more code..
Код с адреса 455659:
add eax, 500
mul eax, edx
ret
Когда выполняется команда call, процессор передает управление на код с адреса 455659, и выполняет его до команды ret, а затем возвращает управление команде следующей за call. Код который вызывается командой call называется процедурой. Вы можете поместить код, который вы часто используете в процедуру и каждый раз когда он вам нужен вызывать его командой call.
Подробнее: команда call помещает регистр EIP (указатель на следующюю команду, которая должна быть выполнена) в стек, а команда ret извлекает его и передаёт управление этому адресу. Вы также можете определить аргументы, для вызываемой программы (процедуры). Это можно сделать через стек:
push значение_1
push значение_2
call procedure
Внутри процедуры, аргументы могут быть прочитаны из стека и использованы. Локальные переменные, т.е. данные, которые необходимы только внутри процедуры, также могут быть сохранены в стеке. Я не буду подробно рассказывать об этом, потому, что это может быть легко сделано в ассемблерах MASM и TASM. Просто запомните, что вы можете делать процедуры и что они могут использовать параметры.
Одно важное замечание:
регистр eax почти всегда используется для хранения результата процедуры.
Это также применимо к функциям windows. Конечно, вы можете использовать любой другой регистр в ваших собственных процедурах, но это стандарт.
Что такое mov ассемблер
При изучении данной темы мы рассмотрим всего три типа операндов, которые могут встречаться в любой команде: непосредственно заданное значение (immediate), регистр (register) и память (memory). Из всех перечисленных здесь типов только последний (память) довольно труден для освоения. Список условных обозначений возможных типов операндов, взятых из руководства фирмы Intel по процессору Pentium, приведен в табл. 1. Довайте изучим его, поскольку с этого момента мы будем активно пользоваться этими обозначениями при описании синтаксиса команд процессоров Intel.
Таблица 1. Условное обозначение типов операндов.
Один из 8-разрядных регистров общего назначения: АН, AL, BH, BL, CH, CL, DH, DL
Один из 16-разрядных регистров общего назначения: АХ, BX, СХ, DX, SI, DI, SP, BP
Один из 32-разрядных регистров общего назначения: ЕАХ, ЕВХ, ЕСХ, EDX, ESI, EDI, ESP, EBP
Произвольный регистр общего назначения
Один из 16-разрядных сегментных регистров: CS, DS, SS, ES, FS, GS
Непосредственно заданное 8-разрядное значение (байт)
Непосредственно заданное 16-разрядное значение (слово)
Непосредственно заданное 32-разрядное значение (двойное слово)
Непосредственно заданное 8-, 16- или 32-разрядное значение
8-разрядный операнд, в котором закодирован один из 8-разрядных регистров общего назначения или адрес байта в памяти
16-разрядный операнд, в котором закодирован один из 16-разрядных регистров общего назначения или адрес слова в памяти
32-разрядный операнд, в котором закодирован один из 32-разрядных регистров общего назначения или адрес двойного слова в памяти
Адрес 8-, 16- или 32-разрядного операнда в памяти
Команда MOV копирует данные из операнда-источника в операнд-получатель. Она относится к группе команд пересылки данных (data transfer) и используется в любой программе. Команда MOV является двуместной (т.е. имеет два операнда): первый операнд определяет получателя данных (destination), а второй — источник данных (source):
При выполнении этой команды изменяется содержимое операнда-получателя, а содержимое операнда-источника не меняется. Принцип пересылки данных справа налево соответствует принятому в операторах присваивания языков высокого уровня, таких как C ++:
Практически во всех командах ассемблера операнд-получатель находится слева, а операнд-источник— справа.
В команде MOV могут использоваться самые разные операнды. Кроме того, необходимо учитывать следующие правила и ограничения:
1. Оба операнда должны иметь одинаковую длину.
2. В качестве одного из операндов обязательно должен использоваться регистр (т.е. пересылки типа «память-память» в команде MOV не поддерживаются).
4. Нельзя переслать непосредственно заданное значение в сегментный регистр.
Ниже приведены варианты использования команды MOV с разными операндами (кроме сегментных регистров):
Сегментные регистры в команде MOV обычно используются только в программах, написанных для реального или виртуального режимов работы процессора. При этом могут существовать следующие ее формы (следует учитывать, что регистр CS нельзя указывать в качестве получателя данных):
Пересылка типа «память—память». С помощью одной команды MOV нельзя напрямую переслать операнд из одной области памяти в другую. Поэтому вначале нужно загрузить исходное значение в один из регистров общего назначения, а затем переслать его в нужное место памяти.
При записи целочисленной константы в переменную или загрузке ее в регистр нужно не забывать про ее минимальную длину в байтах.
Команда MOVZX (Move With Zero-Extend, или Переместить и дополнить нулями) копирует содержимое исходного операнда в больший по размеру регистр получателя данных. При этом оставшиеся неопределенными биты регистра-получателя (как правило, старшие 16 или 24 бита) сбрасываются в ноль. Эта команда используется только при работе с беззнаковыми целыми числами. Существует три варианта команды MOVZX:
Условные обозначения операндов этой команды приведены в табл. 1. В каждом из приведенных трех вариантов первый операнд является получателем, а второй — источником данных. В качестве операнда-получателя может быть задан только 16- или 32-разрядный регистр. На рис. 8 показано, как 8-разрядный исходный операнд загружается с помощью команды MOVZX в 16-разрядный регистр.
Рис. 8. Иллюстрация работы команды MOVZX.
В приведенном ниже примере используются все три варианта команды MOVZX с разными размерами операндов.
movzx eax, bx ; EAX = 0000A69Bh
movzx edx, bl ; EDX = 0000009Bh
movzx cx, bl ; CX = 009Bh
А в следующем примере в качестве исходного операнда используются переменные разной длины, расположенные в памяти, но полученный результат будет идентичен предыдущему примеру.
short word1 = 0xA69B;
MOVSX r 32, r / m 16
Рис. 9. Иллюстрация работы команды MOVSX.
В приведенном ниже примере используются все три варианта команды MOVSX с разными размерами операндов.
movsx eax, bx ; EAX = FFFFA69Bh
movsx edx, bl ; EDX = FFFFFF9Bh
movsx cx, bl ; CX = FF9Bh
Система команд x86
Влияние команды на флаги и форматы команды:
Описание:
Команда MOV копирует второй операнд (операнд-источник) в первый операнд (операнд-назначение). Оба операнда могут быть регистрами общего назначения, сегментными регистрами, непосредственными значениями и переменными в памяти. Оба операнда должны иметь одинаковую размерность — байт, слово или двойное слово.
Если операнд-назначение — сегментный регистр (DS, ES, FS, GS или SS), тогда в скрытую часть этого регистра также загружаются данные из соответствующего дескриптора. Эти данные извлекаются из элемента таблицы дескрипторов для данного селектора. Сегментный регистр CS не может быть загружен командой MOV. Попытка использования соответствующего кода приводит к генерации особой ситуации #UD. Для загрузки регистра CS должны использоваться команды JMP, CALL или RET.
Пустой селектор (значения 0000, … 0003) может быть загружен в регистры DS, ES, FS и GS не вызывая особой ситуации. Однако попытка использования нулевых селекторов при обращении к памяти вызывает особую ситуацию #GP(0), и никакого обращения к памяти не происходит.
Ниже представлен листинг всех проверок и действий, предпринимаемых процессором при загрузке сегментного регистра в защищенном режиме:
IF (Селектор не нулевой) THEN #GP(0); FI;
Индекс селектора должен попадать в пределы таблицы дескрипторов, иначе #GP(Селектор);
Поле RPL селектора должно быть равно CPL, иначе #GP(Селектор);
AR байт должен задавать сегмент данных, доступный для записи, иначе #GP(Селектор);
Поле DPL AR байта должно быть равно CPL, иначе #GP(Селектор);
Сегмент должен быть помечен, как присутствующий, иначе #SS(Селектор);
Загрузить SS селектором;
Загрузить SS дескриптором;
IF (загружается DS, ES, FS или GS не нулевым селектором)
Индекс селектора должен попадать в пределы таблицы дескрипторов, иначе #GP(Селектор);
AR байт должен задавать сегмент данных, или кодовый сегмент доступный для чтения, иначе #GP(Селектор);
IF (Данные или несогласованный код)
THEN RPL и CPL должны быть меньше или равны DPL в AR байте, иначе #GP(Селектор);
Сегмент должен быть помечен, как присутствующий, иначе #NP(Селектор);
Загрузить селектор в сегментный регистр;
Загрузить дескриптор в сегментный регистр;
IF (Загружается DS, ES, FS или GS нулевым селектором)
Загрузить селектор в сегментный регистр;
Очистить внутренний флаг корректности дескриптора (descriptor valid bit);
Команда загрузки сегмента стека SS запрещает все прерывания до завершения выполнения следующей команды (которая может быть командой MOV в ESP). Более эффективным методом загрузки нового указателя стека является команда LSS. Существуют и другие команды, которые задерживают прием прерываний при выполнении следующей за ними команды, но комбинация таких команд (например, STI и MOV SS,EAX) не означает, что прерывания не будут восприниматься на протяжении двух команд. Такие последовательности могут вызвать серьезные сбои, т.к. станет возможным поступление прерывания сразу после команды загрузки стекового сегмента SS.
В процессорах 32-разрядной архитектуры (Intel386, …) команды пересылки между сегментными регистрами и регистрами общего назначения не требуют наличия префикса 16-битного размера операнда (66h) не зависимо от текущего режима работы. Т.е. в этом случае всегда пересылаются 16-битные данные. Многие ассемблеры при встрече подобных мнемоник (например, MOV DS,AX) автоматически вставляют префикс 16-битного размера операнда перед командой пересылки. Это не влияет на результат исполнения команды, а замедляет только время исполнения. Простейшим выходом из данной ситуации является программирование 32-битной мнемоники (MOV DS,EAX), она преобразуется ассемблером в тот же самый код операции, но без префикса размера операнда. Поскольку пересылка данных в этом случае происходит межу 16-битным и 32-битным регистрами, то в 32-битном регистре в операции учавствуют только его младшие 16 бит. Если 32-битный регистр является операндом-назначением такой операции, то значения в его старших 16 битах после окончания пересылки могут быть различны в различных моделях процессоров. В Pentium Pro, … они заполняются нулями, а для более ранних процессоров Intel их значения не определены.
Операция:
Особые ситуации защищенного режима:
#GP(0), если операнд-назначение находится в сегменте, запрещенном для записи, если используется некорректный эффективный адрес операнда в памяти в сегментах CS, DS, ES, FS, GS или нулевой селектор, а также при попытке загрузки регистра SS нулевым селектором.
#GP(Селектор), если индекс загруженного селектора не попадает в пределы таблицы дескрипторов, если при загрузке регистра SS запрашиваемый уровень привилегий селектора RPL или уровень привилегий соответствующего дескриптора сегмента DPL не равны текущему уровню привилегий CPL, если регистр SS загружается селектором, который указывает на сегмент запрещенный для записи, если регистр DS, ES, FS или GS загружается селектором сегмента, который не является доступным для чтения кодовым сегментом или сегментом данных, если регистр DS, ES, FS или GS загружается селектором сегмента, который является сегментом данных или несогласованным кодовым сегментом, и уровень привилегий дескриптора этого сегмента DPL меньше по значению запрашиваемого уровня привилегий селектора RPL и текущего уровня привилегий CPL.
#SS(0) при использовании некорректного эффективного адреса в сегменте SS.
#SS(Селектор), если регистр SS загружается селектором сегмента, который помечен как неприсутствующий.
#NP(Селектор), если регистр DS, ES, FS или GS загружается селектором сегмента, который помечен как неприсутствующий.
#PF(Код ошибки), страничная ошибка.
#AC(0) при невыровненной ссылке в память при текущем уровне привилегий равном 3.
#UD при попытке загрузки регистра CS.
Особые ситуации режима реальной адресации:
#GP, если любая часть операнда находится вне пространства эффективных адресов в сегментах CS, DS, ES, FS или GS.
#SS, если любая часть операнда находится вне пространства эффективных адресов в сегменте SS.
#UD при попытке загрузки регистра CS.
Особые ситуации режима V86:
Такие же, как и в режиме реальной адресации.
#PF(Код ошибки), страничная ошибка.
#AC(0) при невыровненной ссылке в память.
Замечание:
В процессоре Pentium III существуют некоторые ситуации, когда отладчик будет получать неверную информацию в регистрах отладки от команд MOV SS и POP SS. Обратитесь к технической документации Intel за описанием всех возможных случаев проявления ошибки.
Что такое mov ассемблер
9.1 АССЕМБЛЕР. ЭТАПЫ РАЗРАБОТКИ ПРОГРАММЫ.
Язык программирования наиболее полно учитывающий особенности «родного» микропроцессора и содержащий мнемонические обозначения машинных команд называется Ассемблером. Программа, написанная на Ассемблере называется исходной программой. Далее остановимся на версии, называемой Турбо Ассемблер.
Действия обусловленные операциями перечисленными в пп.б,в,г выполняются на этапе трансляции, т.е. являются командами Ассемблеру. Операции, называемые командами или инструкциями выполняются во время выполнения программы, т.е. являются командами микропроцессору.
9.2 ФОРМАТ КОМАНД И ИХ КЛАССИФИКАЦИЯ
Инструкция записывается на отдельной строке и включает до четырех полей, необязательные из которых выделены [ ]:
Операндами могут быть явно или неявно задаваемые двоичные наборы, над которыми производятся операции.Операнды приводятся в одной из четырех систем счисления и должны оканчиваться символом b(B), o(O), d(D), h(H) для 2, 8, 10 или 16-ной СС. К шестнадцатиричному числу добавляется слева ноль, если оно начинается с буквы.
Для МП 1810ВМ86 (8086) команда занимает от одного до шести байтов. Первым байтом команды всегда является код операции, например код команды INT XXh равен CD(HEX).
Большинство остальных способов адресации являются комбинациями или видоизменениями перечисленнных.
В первом случае операнд(ы) располагаются в регистрах микропроцессора (МП), например по команде MOV AX,CX пересылается содержимое CX в AX.
При непосредственной адресации операнд располагается в памяти непосредственно за КОП, инструкция MOV AL,0f5h записывает число 245(f5) в регистр AL.
В случае прямой адресации за КОП следует не сам операнд, а адрес ячейки памяти или внешнего устройства, например команда IN AL,40h вводит байт данных из внешнего устройства с адресом 40h.
Косвенная адресация отличается от регистровой тем, что в регистре хранится адрес операнда, т.е. по команде MOV AL,[BX] в аккумулятор al будет записано число из ячейки памяти с адресом, хранящимся в регистре BX.
Стековая адресация производится к операндам расположенным в области памяти, называемой стек.
9.3 НЕКОТОРЫЕ ОПЕРАТОРЫ, ПРЕДОПРЕДЕЛЁННЫЕ ИМЕНА, ДИРЕКТИВЫ И КОМАНДЫ АССЕМБЛЕРА 80X86(8088)
9.3.1 ПРЕДОПРЕДЕЛЕННЫЕ ИМЕНА
в сегментном регистре DS теперь адрес сегмента данных.
9.3.2 ОПЕРАТОРЫ
mov si, 01010101b SHR 3; в регистр SI будет загружено число 0Ah (00001010).
mov dl, (10d OR 5d) XOR 7d; (dl) будет равно 8.
mov dl,[es:bx]; поместить в dl байт данных из сегмента es и отстоящий от его начала на (bx) байтов (смещение).
mov bx, OFFSET table
9.3.3 ДИРЕКТИВЫ (ПСЕВДООПЕРАТОРЫ)
videoram = 0B800h; присвоение videoram = 0B000h;
Вызов этого макроса производится командой: Swap m,n
.MODEL tiny;под программу,данные и стек отводится один общий сегмент (64 Kb).
.STACK 200h; выделяет 512 байтов для стека.
9.3.4 КОМАНДЫ ПЕРЕСЫЛКИ
mov al,[table + bx]
mov al,[table + bx]
2. PUSH RP; поместить на вершину стека содержимое пары регистров RP (например push bx).
3. POP RP; снять с вершины стека два байта и поместить в пару RP (например pop ax).
4. XCHG DST, SRC; поменять местами содержимое (DST) и (SRC). Оба операнда не могут быть одновременно содержимым ячеек памяти.
5. XLAT SRC; извлечь из таблицы с начальным адресом SRC байт данных имеющий номер от начала таблицы = (AL), и поместить его в AL. Адрес SRC должен находиться в регистре BX. Другой вариант: XLATB.
6. IN ACCUM, PORT; поместить в аккумулятор AL или AX байт или слово из порта с адресом PORT. Если адрес порта FF, то адрес порта указывается косвенно, через содержимое регистра DX (специальная функция регистра общего назначения).
7. OUT PORT, ACCUM; переслать из аккумулятора AL или AX байт или слово в ВУ с символическим адресом PORT.
8. LEA RP,M; загрузить в регистр RP эффективный адрес (смещение) ячейки памяти с символическим адресом M.
9.3.5 АРИФМЕТИЧЕСКИЕ КОМАНДЫ
1. ADD DST, SRC; сложить содержимое SRC и DST и результат переслать в DST.
add al, [mem_byte]; mem_byte однобайтовая ячейка памяти
add [mem_word], dx; mem_word двухбайтовая ячейка памяти
2. INC DST; увеличить (DST) на 1 (инкремент (DST)).
3. SUB DST, SRC; вычесть (SRC) из (DST) и результат поместить в DST.
4. DEC DST; декремент (DST).
5. CMP DST, SRC; сравнить содержимое DST и SRC. Эта команда выполняет вычитание (SRC) из (DST) но разность не помещает в DST и по результату операции воздействует на флаги.
BX
4. NOT DST; инверсия всех битов приемника.
5. TEST DST, SRC; выполняет операцию AND над операндами, но воздействует только на флаги и не изменяет самих операндов.
6. SHR DST, CNT; логический сдвиг вправо, освобождающиеся слева биты заполняются нулем, крайний правый бит выталкивается во флаг CF. Операнд DST может быть ячейкой памяти.
до сдвига | 1 | 0 | 1 | 1 | 0 | 0 | 1 | 0 | (CF)=X |
после сдвига | 0—> | 0 | 1 | 0 | 1 | 1 | 0 | 0 | 1 | ——> | (CF)=0 |
7. SHL DST, CNT; логический сдвиг влево.
8. RLC DST, CNT; циклический сдвиг влево через перенос
9. RRC DST, CNT;циклический сдвиг вправо через перенос
10. ROR DST, CNT;циклический сдвиг влево
11. ROL DST, CNT;циклический сдвиг вправо
9.3.7 КОМАНДЫ ПЕРЕДАЧИ УПРАВЛЕНИЯ
1. CALL SUBR; вызов подпрограммы с адресом SUBR;
3. JMP NAME; безусловный переход к команде с символическим адресом NAME.
4. JA NAME или JNBE NAME; условный переход, если, например, в результате сравнения CMP DST, SRC приемник по абсолютной величине больше источника, то перейти к метке name.
5. JB NAME или JNAE NAME; условный переход, если, например, в результате сравнения CMP DST, SRC приемник по абсолютной величине меньше источника, то перейти к метке name (команды п4 и п5 выполняются по результатам выполнения операций над беззнаковыми числами).
7. JNZ NAME или JNE NAME; переход по «не нулю». (команды п6 и п7 выполняются по результатам выполнения операций над числами cо знаком ).
9.3.8 КОМАНДЫ УПРАВЛЕНИЯ ЦИКЛАМИ
1. LOOP NAME; эта команда неявно уменьшает (CX) на 1 и осуществляет переход к ближней метке, если (CX) не равно 0.
2. LOOPZ NAME или LOOPE NAME кроме того осуществляет проверку ZF флага. Поэтому цикл заканчивается по условию, когда (CX) = 0 или (ZF) = 0 или и то и другое вместе. Т.о. эта команда служит для обнаружения первого ненулевого результата.
9.3.9 КОМАНДЫ ОБРАБОТКИ СТРОК (ЦЕПОЧЕК БАЙТОВ)
1. LODSB; команда lodsb загружает байт адресованный регистром SI из сегмента данных, и увеличивает SI на 1, если перед этим была введена команда CLD (очистить флаг направления DF) и уменьшает SI на 1, если была использована команда STD (установить флаг направления).
2. MOVSB; эта команда перемещает один байт из ячейки памяти с адресом в регистре SI в ячейку памяти с адресом в регистре DI и увеличивает (SI) и (DI) на 1. Значение SI может находиться, как в сегменте данных DS, так и в дополнительном сегменте ES. Значение DI может находиться только в дополнительном сегменте ES.
3. REP ;префикс повторения команды. Например окончание предыдущей программы может быть записано в виде:
5. REPZ или REPE; префикс повторения. Выполнение команды завершается, когда (CX) = 0 или (ZF) = 0.
В конце этого примера номер первого несовпадающего байта (CX) = 5.
9.3.10 КОМАНДЫ УПРАВЛЕНИЯ МИКРОПРОЦЕССОРОМ
1. CLC; сбросить флаг переноса (CF) = 0.
2. STC; установить флаг переноса (CF) = 1.
3. CMC; инвертировать флаг пнреноса.
4. CLD; очистить флаг направления (DF) = 0, в этом случае операции над строками (цепочками байтов) будут производиться от младшего адреса к старшему.
5. STD; установить флаг направления (DF) = 1,обработка цепочек байтов производится от старшего адреса к младшему.
6. STI; установить флаг прерываний (IF) = 1, разрешить прерывания от внешних устройств.
7.CLI; очистить флаг прерываний.
8. NOP; холостая операция.
9.3.11 КОМАНДЫ ПРЕРЫВАНИЙ
1. INT INUM; эта команда вызывает программное прерывание, то есть переход к ячейке памяти с адресом хранящимся в четырех байтах, начиная с адреса INUM * 4, где INUM = (0. 255). Это 4-х байтовое число является указателем подпрограммы обработчика данного прерывания, и иначе называется вектором прерывания.Таким образом первый килобайт памяти 256 * 4 отводится под векторы прерываний.
Операции инициируемые программными прываниями определяются кодом в регистре AH, например:
9.3.12 ВЛИЯНИЕ КОМАНД НА ФЛАГИ
В таблицу включены только те инструкции, которые влияют на флаги.