Заглавная страница Избранные статьи Случайная статья Познавательные статьи Новые добавления Обратная связь FAQ Написать работу КАТЕГОРИИ: АрхеологияБиология Генетика География Информатика История Логика Маркетинг Математика Менеджмент Механика Педагогика Религия Социология Технологии Физика Философия Финансы Химия Экология ТОП 10 на сайте Приготовление дезинфицирующих растворов различной концентрацииТехника нижней прямой подачи мяча. Франко-прусская война (причины и последствия) Организация работы процедурного кабинета Смысловое и механическое запоминание, их место и роль в усвоении знаний Коммуникативные барьеры и пути их преодоления Обработка изделий медицинского назначения многократного применения Образцы текста публицистического стиля Четыре типа изменения баланса Задачи с ответами для Всероссийской олимпиады по праву Мы поможем в написании ваших работ! ЗНАЕТЕ ЛИ ВЫ?
Влияние общества на человека
Приготовление дезинфицирующих растворов различной концентрации Практические работы по географии для 6 класса Организация работы процедурного кабинета Изменения в неживой природе осенью Уборка процедурного кабинета Сольфеджио. Все правила по сольфеджио Балочные системы. Определение реакций опор и моментов защемления |
Адресация по базе со смещениемСодержание книги Похожие статьи вашей тематики
Поиск на нашем сайте
Адресация по базе со смещением является комбинацией двух предыдущих методов адресации. Адрес искомой ячейки определяется как сумма базового адреса, указанного в одном из регистров, и непосредственно указанного смещения. Следующая команда mov ax,[bx+2] помещает в регистр AX слово, находящееся в сегменте, указанном в DS, со смещением на 2 большим, чем число, находящееся в BX. Так как слово занимает ровно два байта, эта команда поместила в AX слово, непосредственно следующее за тем, которое есть в предыдущем примере. Такая форма адресации используется в тех случаях, когда в регистре находится адрес начала структуры данных, а доступ надо осуществить к какому-нибудь элементу этой структуры. Другое важное применение адресации по базе со сдвигом — доступ из подпрограммы к параметрам, переданным в стеке, используя регистр BP (EBP) в качестве базы и номер параметра в качестве смещения. Другие допустимые формы записи этого способа адресации: mov ax,[bp]+2 mov ax,2[bp] До 80386 в качестве базового регистра можно было использовать только BX, BP, SI или DI и сдвиг мог быть только байтом или словом (со знаком). Начиная с 80386 и старше, процессоры Intel позволяют дополнительно использовать EAX, EBX, ECX, EDX, EBP, ESP, ESI и EDI, так же как и для обычной косвенной адресации. С помощью этого метода можно организовывать доступ к одномерным массивам байт: смещение соответствует адресу начала массива, а число в регистре — индексу элемента массива, который надо считать. Очевидно, что если массив состоит не из байт, а из слов, придется умножить базовый регистр на два, а если из двойных слов — на четыре. Для этого предусмотрен следующий специальный метод адресации. Косвенная адресация с масштабированием Этот метод полностью идентичен предыдущему, за исключением того, что с его помощью можно прочитать элемент массива слов, двойных слов или учетверенных слов, просто поместив номер элемента в регистр: mov ax,[esi*2]+2 Множитель, который может быть равен 1, 2, 4 или 8, соответствует размеру элемента массива — байту, слову, двойному слову, учетверенному слову соответственно. Из регистров в этом варианте адресации можно использовать только ЕАХ, ЕВХ, ЕСХ, EDX, ESI, EDI, ЕВР, ESP, но не SI, DI, ВР или SP, которые можно было использовать в предыдущих вариантах. Адресация по базе с индексированием В этом методе адресации смещение операнда в памяти вычисляется как сумма чисел, содержащихся в двух регистрах, и смещения, если оно указано. Все следующие команды — это разные формы записи одного и того же действия: mov ax [bx+si+2] mov ax,[bx][si]+2 mov ax,[bx+2][si] mov ax,[bx][si+2] mov aх,2[bx][si] В регистр АХ помещается слово из ячейки памяти со смещением, равным сумме чисел, содержащихся в ВХ, SI, и числа 2. Из 16-битных регистров так можно складывать только ВХ + SI, ВХ + DI, ВР + SI и ВР + DI, а из 32-битных — все восемь регистров общего назначения. Так же как и для прямой адресации, вместо непосредственного указания числа можно использовать имя переменной, заданной одной из директив определения данных. Так можно считать, например, число из двумерного массива: если задана таблица 10´10 байт, 2 — смещение ее начала от начала сегмента данных (на практике будет использоваться имя этой таблицы), ВХ = 20, а SI = 7, приведенные команды прочитают слово, состоящее из седьмого и восьмого байт третьей строки. Если таблица состоит не из одиночных байт, а из слов или двойных слов, удобнее использовать следующую, наиболее полную форму адресации. Адресация по базе с индексированием и масштабированием Это самая полная возможная схема адресации, в которую входят все случаи, рассмотренные ранее, как частные. Полный адрес операнда можно записать как выражение, представленное на рисунке 6.
Рис. 6. Полная форма адресации
Смещение может быть байтом или двойным словом. Если ESP или ЕВР используются в роли базового регистра, селектор сегмента операнда берется по умолчанию из регистра SS, во всех остальных случаях из DS. Основные непривилегированные команды
В этой главе описаны все непривилегированные команды процессоров Intel серии х86, исключая команды расширений для работы с числами повышенной точности (NPX и MMX). Для каждой команды указана форма записи, название и модель процессоров Intel, начиная с которой она поддерживается: 8086, 80186, 80286, 80386, 80486, Р5 (Pentium), Р6 (Pentium Pro и Pentium II). Пересылка данных Команды пересылки данных осуществляют условный или безусловный обмен данными между регистрами и ячейками памяти, в том числе стековой, а также ввод и вывод данных через порты устройств.
• Команда: MOV приемник,источник • Назначение: Пересылка данных • Процессор: 8086 Базовая команда пересылки данных. Копирует содержимое источника в приемник, источник не изменяется. Команда MOV действует аналогично операторам присваивания из языков высокого уровня, то есть команда mov dx, bx эквивалентна выражению ax:=bx; языка Паскаль или ах=bх; языка С, за исключением того, что команда ассемблера позволяет работать не только с переменными в памяти, но и со всеми регистрами процессора. В качестве источника для MOV могут использоваться: число (непосредственный операнд), регистр общего назначения, сегментный регистр или переменная (то есть операнд, находящийся в памяти). В качестве приемника — регистр общего назначения, сегментный регистр (кроме CS) или переменная. Оба операнда должны быть одного и того же размера — байт, слово или двойное слово. Нельзя выполнять пересылку данных с помощью MOV из одной переменной в другую, из одного сегментного регистра в другой и нельзя помещать в сегментный регистр непосредственный операнд — эти операции выполняют двумя командами MOV (из сегментного регистра в обычный и уже из него в другой сегментный) или парой команд PUSH/POP. Загрузка регистра SS командой MOV автоматически запрещает прерывания до окончания следующей за этим команды MOV, так что можно загрузить SS и ESP двумя последовательными командами MOV, не опасаясь, что в этот момент произойдет прерывание, обработчик которого получит неправильный стек. В любом случае для загрузки значения в регистр SS предпочтительнее команда LSS. • Команда: CMOV cc приемник,источник • Назначение: Условная пересылка данных • Процессор: Р6 Это набор команд, которые копируют содержимое источника в приемник, если удовлетворяется то или иное условие (см. табл. 5). Источником может быть регистр общего назначения или переменная, а приемником — только регистр. Условие, которое должно удовлетворяться, — просто равенство нулю или единице тех или иных флагов из регистра FLAGS, но, если использовать команды CMOVcc сразу после команды СМР (сравнение) с теми же операндами, условия приобретают особый смысл, например: cmp ax,bx; сравнить ax и bx cmovl ax,bx; если ax < bx, скопировать bx в ах Слова «выше» и «ниже» в таблице 5 относятся к сравнению чисел без знака, слова «больше» и «меньше» учитывают знак.
• Команда: XCHG операнд1,операнд2 • Назначение: Обмен операндов между собой • Процессор: 8086 Содержимое операнда 2 копируется в операнд 1, а старое содержимое операнда 1 — в операнд 2. XCHG можно выполнять над двумя регистрами или над регистром и переменной.
xchg еах,ebx; то же, что три команды на языке С: ; temp = eax; eax = ebx; ebx = temp, xchg аl,al; а эта команда не делает ничего
• Команда: BSWAP регистр32 • Назначение: Обмен байт внутри регистра • Процессор: 80486 Обращает порядок байт в 32-битном регистре. Биты 0 – 7 (младший байт младшего слова) меняются местами с битами 24 – 31 (старший байт старшего слова), а биты 8 – 15 (старший байт младшего слова) меняются местами с битами 16 – 23 (младший байт старшего слова).
mov eax,12345678h bswap eax; теперь в eax находится 78563412h Таблица 5. Разновидности команды CMOVcc
Чтобы обратить порядок байт в 16-битном регистре, следует использовать команду XCHG: xchg al,ah; обратить порядок байт в АХ
• Команда: PUSH источник • Назначение: Поместить данные в стек • Процессор: 8086 Помещает содержимое источника в стек. Источником может быть регистр, сегментный регистр, непосредственный операнд или переменная. Фактически эта команда уменьшает ESP на размер источника в байтах (2 или 4), а затем копирует содержимое источника в память по адресу SS:[ESP]. Команда PUSH практически всегда используется в паре с POP (считать данные из стека). Так, например, чтобы скопировать содержимое одного сегментного регистра в другой (что нельзя выполнить одной командой MOV), можно использовать такую последовательность команд: push cs pop ds; теперь DS указывает на тот же сегмент, что и CS Другое частое применение команд PUSH/POP — временное хранение переменных, например: push eax; сохраняет текущее значение EAX ...; здесь располагаются какие-нибудь команды, ; которые используют EAX, например CMPXCHG pop eax; восстанавливает старое значение EAX
Начиная с 80286, команда PUSH ESP (или SP) помещает в стек значение ESP до того, как эта же команда его уменьшит, в то время как на 8086 SP помещался в стек уже уменьшенным на два.
• Команда: POP приемник • Назначение: Считать данные из стека • Процессор: 8086 Помещает в приемник слово или двойное слово, находящееся в вершине стека, увеличивая ESP на 2 или 4 соответственно. POP выполняет действие, полностью обратное PUSH. Приемником может быть регистр общего назначения, сегментный регистр, кроме CS (чтобы загрузить CS из стека, надо воспользоваться командой RET), или переменная. Если в роли приемника выступает операнд, использующий ESP для косвенной адресации, команда POP вычисляет адрес операнда уже после того, как она увеличивает ESP.
• Команда: PUSHA, PUSHAD • Назначение: Поместить в стек все регистры общего назначения • Процессор: 80186, 80386 PUSHA помещает в стек регистры в следующем порядке: AX, CX, DX, ВХ, SP, ВР, SI и DI. PUSHAD помещает в стек ЕАХ, ЕСХ, EDX, ЕВХ, ESP, EBP, ESI и EDI. (В случае SP и ESP используется значение, которое находилось в этом регистре до начала работы команды.) В паре с командами POPA/POPAD, считывающими эти же регистры из стека в обратном порядке, это позволяет писать подпрограммы (обычно обработчики прерываний), которые не должны изменять значения регистров по окончании своей работы. В начале такой подпрограммы вызывают команду PUSHA, а в конце — РОРА. На самом деле PUSHA и PUSHAD — одна и та же команда с кодом 60h. Ее поведение определяется тем, выполняется ли она в 16- или в 32-битном режиме. Если программист использует команду PUSHAD в 16-битном сегменте или PUSHA в 32-битном, ассемблер просто записывает перед ней префикс изменения размерности операнда (66h). Это же будет распространяться на некоторые другие пары команд: РОРА/POPAD, POPF/POPFD, PUSHF/PUSHFD, JCXZ/JECXZ, CMPSW/CMPSD, INSW/INSD, LODSW/LODSD, MOVSW/MOVSD, OUTSW/OUTSD, SCASW/SCASD и STOSW/ STOSD.
• Команда: РОРА, POPAD • Назначение: Загрузить из стека все регистры общего назначения • Процессор: 80186, 80386 Эти команды выполняют действия, полностью обратные действиям PUSHA и PUSHAD, за исключением того, что помещенное в стек значение SP или ESP игнорируется. РОРА загружает из стека DI, SI, ВР, увеличивает SP на два, загружает ВХ, DX, CX, AX, а POPAD загружает EDI, ESI, ЕВР, увеличивает ESP на 4 и загружает ЕВХ, EDX, ЕСХ, ЕАХ.
• Команда: IN приемник,источник • Назначение: Считать данные из порта • Процессор: 8086 Копирует число из порта ввода-вывода, номер которого указан в источнике, в приемник. Приемником может быть только AL, АХ или ЕАХ. Источник — или непосредственный операнд, или DX, причем можно указывать только номера портов не больше 255.
• Команда: OUT приемник,источник • Назначение: Записать данные в порт • Процессор: 8086 Копирует число из источника (AL, AX или ЕАХ) в порт ввода-вывода, номер которого указан в приемнике. Приемник может быть либо непосредственным номером порта, либо регистром DX. На командах IN и OUT строится все общение процессора с устройствами ввода-вывода — клавиатурой, жесткими дисками, различными контроллерами, и используются они, в первую очередь, в драйверах устройств. Например, чтобы включить динамик PC, достаточно выполнить команды:
in al,61h or al,3 out 61h,al
• Команда: CWD • Назначение: Конвертирование слова в двойное слово • Процессор: 8086 • Команда: CDQ • Назначение: Конвертирование двойного слова в учетверенное • Процессор: 80386 Команда CWD превращает слово в AХ в двойное слово, младшая половина которого (биты 0 – 15) остается в АХ, а старшая (биты 16 – 31) располагается в DX. Команда CDQ выполняет аналогичное действие по отношению к двойному слову в ЕАХ, расширяя его до учетверенного слова в EDX:EAX. Эти команды всего лишь устанавливают все биты регистра DX или EDX в значение, равное значению старшего бита регистра АХ или ЕАХ, сохраняя таким образом его знак.
• Команда: CBW • Назначение: Конвертирование байта в слово • Процессор: 8086 • Команда: CWDE • Назначение: Конвертирование слова в двойное слово • Процессор: 80386 CBW расширяет байт, находящийся в регистре AL, до слова в АХ, CWDE расширяет слово в АХ до двойного слова в ЕАХ. CWDE и CWD отличаются тем, что CWDE располагает свои результат в ЕАХ, в то время как CWD, команда, выполняющая точно такое же действие, располагает результат в паре регистров DX:AX. Так же как и команды CWD/CDQ, расширение выполняется путем установки каждого бита старшей половины результата равным старшему биту исходного байта или слова, то есть:
mov al,0F5h; AL = 0F5h = 245 = -11 cbw; теперь АХ = 0FFF5h = 55 525 = -11 Так же как и в случае с командами PUSHA/PUSHAD, пара команд CWD/CDQ — это одна команда с кодом 99h, и пара команд CBW/CWDE — одна команда с кодом 98h. Интерпретация этих команд зависит от того, в каком (16-битном или в 32-битном) сегменте они исполняются, и точно так же, если указать CDQ или CWDE в 16-битном сегменте, ассемблер поставит префикс изменения разрядности операнда.
• Команда: MOVSX приемник,источник • Назначение: Пересылка с расширением знака • Процессор: 80386 Копирует содержимое источника (регистр или переменная размером в байт или слово) в приемник (16- или 32-битный регистр) и расширяет знак аналогично командам CBW/CWDE.
• Команда: MOVZX приемник,источник • Назначение: Пересылка с расширением нулями • Процессор: 80386 Копирует содержимое источника (регистр или переменная размером в байт или слово) в приемник (16- или 32-битный регистр) и расширяет нулями, то есть команда movzx ах, bl эквивалентна паре команд mov al,bl mov ah,0
• Команда: XLAT адрес XLATB • Назначение: Трансляция в соответствии с таблицей • Процессор: 8086 Помещает в AL байт из таблицы в памяти по адресу DS:BX (или DS:EBX) со смещением относительно начала таблицы, равным AL. В качестве аргумента для XLAT в ассемблере можно указать имя таблицы, но эта информация никак не используется процессором, и в любом случае необходимо заполнять регистр BX (EBX) адресом таблицы. Однако при указании аргумента-имени можно использовать переопределение сегмента ES: (если таблица расположена в дополнительном сегменте данных). Применение формы записи команды XLATB не допускает переопределения сегмента. Эта команда часто используется для преобразований значений цифр в ASCII-формат или различных перекодировок (например, из ASCII в EBCDIC или KOI-8). Впрочем, преобразование цифр в ASCII-форму более эффективно выполнить с помощью команды DAS.
• Команда: LEA приемник,источник • Назначение: Вычисление эффективного адреса • Процессор: 8086 Вычисляет эффективный адрес источника (переменная) и помещает его в приемник (регистр). С помощью LEA можно вычислить адрес переменной, которая описана сложным методом адресации, например по базе с индексированием. Если адрес 32‑битный, а регистр-приемник 16-битный, старшая половина вычисленного адреса теряется, если наоборот, приемник 32-битный, а адресация 16-битная, то вычисленное смещение дополняется нулями. Команду LEA можно использовать также для быстрых арифметических вычислений, например умножения: lea bx,[ebx+ebx*4]; ВХ=ЕВХ*5 или сложения: lea ebx,[eax+12]; ЕВХ=ЕАХ+12 (эти команды занимают меньше, чем соответствующие MOV и ADD, и не изменяют флаги). Двоичная арифметика Все команды из этого раздела, кроме команд деления и умножения, изменяют флаги OF, SF, ZF, AF, CF, PF в соответствии с назначением каждого из этих флагов (см. п. 2.1.4).
• Команда: ADD приемник,источник • Назначение: Сложение • Процессор: 8086 Команда выполняет арифметическое сложение приемника и источника, помещает сумму в приемник, не изменяя содержимое источника. Приемник может быть регистром или переменной, источник может быть числом, регистром или переменной, но нельзя использовать переменную одновременно и для источника, и для приемника. Команда ADD никак не различает числа со знаком и без знака, но, употребляя значения флагов CF (перенос при сложении чисел без знака), OF (перенос при сложении чисел со знаком) и SF (знак результата), можно использовать ее и для тех, и для других.
• Команда: ADC приемник,источник • Назначение: Сложение с переносом • Процессор: 8086 Эта команда во всем аналогична ADD, кроме того, что она выполняет арифметическое сложение приемника, источника и флага CF. Пара команд ADD/ADC используется для сложения чисел повышенной точности. Сложим, например, два 64-битных целых числа: пусть одно из них находится в паре регистров EDX:EAX (младшее двойное слово (биты 0 - 31) — в ЕАХ и старшее (биты 32 - 63) — в EDX), а другое — в паре регистров ЕВХ:ЕСХ: add eax,ecx adc edx,ebx Если при сложении младших двойных слов произошел перенос из старшего разряда (флаг CF =1), то он будет учтен следующей командой ADC.
• Команда: XADD приемник,источник • Назначение: Обменять между собой и сложить • Процессор: 80486 Выполняет сложение, помещает содержимое приемника в источник, а сумму операндов — в приемник. Источник всегда регистр, приемник может быть регистром и переменной.
• Команда: SUB приемник,источник • Назначение: Вычитание • Процессор: 8086 Вычитает источник из приемника и помещает разность в приемник. Приемник может быть регистром или переменной, источник может быть числом, регистром или переменной, но нельзя использовать переменную одновременно и для источника, и для приемника. Точно так же, как и команда ADD, SUB не делает различий между числами со знаком и без знака, но флаги позволяют использовать ее как для тех, так и для других.
• Команда: SBB приемник,источник • Назначение: Вычитание с займом • Процессор: 8086 Эта команда во всем аналогична SUB, кроме того, что она вычитает из приемника значение источника и дополнительно вычитает значение флага CF. Так, можно использовать эту команду для вычитания 64-битных чисел в EDX:EAX и ЕВХ:ЕСХ аналогично ADD/ADC: sub еах,есх sbb edx,ebx Если при вычитании младших двойных слов произошел заем, то он будет учтен при вычитании старших.
• Команда: IMUL источник IMUL приемник,источник IMUL приемник,источник1,источник2 • Назначение: Умножение чисел со знаком • Процессор: 8086 Эта команда имеет три формы, различающиеся числом операндов: 1. IMUL источник: источник (регистр или переменная) умножается на AL, АХ или ЕАХ (в зависимости от размера операнда), и результат располагается в AX, DX:AX или EDX:EAX соответственно. 2. IMUL приемник,источник: источник (число, регистр или переменная) умно-жается на приемник (регистр), и результат заносится в приемник. 3. IMUL приемник,источник1,источник2: источник 1 (регистр или переменная) умножается на источник 2 (число), и результат заносится в приемник (регистр). Во всех трех вариантах считается, что результат может занимать в два раза больше места, чем размер источника. В первом случае приемник автоматически оказывается достаточно большим, но во втором и третьем случаях могут произойти переполнение и потеря старших бит результата. Флаги OF и CF будут равны единице, если это произошло, и нулю, если результат умножения поместился целиком в приемник (во втором и третьем случаях) или в младшую половину приемника (в первом случае). Значения флагов SF, ZF, AF и PF после команды IMUL не определены.
• Команда: MUL источник • Назначение: Умножение чисел без знака • Процессор: 8086 Выполняет умножение содержимого источника (регистр или переменная) и регистра AL, АХ, ЕАХ (в зависимости от размера источника) и помещает результат в АХ, DX:AX, EDX:EAX соответственно. Если старшая половина результата (АН, DX, EDX) содержит только нули (результат целиком поместился в младшую половину), флаги CF и OF устанавливаются в 0, иначе — в 1. Значение остальных флагов (SF, ZF, AF и PF) не определено.
• Команда: IDIV источник • Назначение: Целочисленное деление со знаком • Процессор: 8086 Выполняет целочисленное деление со знаком AL, АХ или ЕАХ (в зависимости от размера источника) на источник (регистр или переменная) и помещает результат в AL, АХ или ЕАХ, а остаток — в АН, DX или EDX соответственно. Результат всегда округляется в сторону нуля, знак остатка всегда совпадает со знаком делимого, абсолютное значение остатка всегда меньше абсолютного значения делителя. Значения флагов CF, OF, SF, ZF, AF и PF после этой команды не определены, а переполнение или деление на ноль вызывает исключение #DE (ошибка при делении) в защищенном режиме и прерывание 0 — в реальном.
• Команда: DIV источник • Назначение: Целочисленное деление без знака • Процессор: 8086 Выполняет целочисленное деление без знака AL, АХ или ЕАХ (в зависимости от размера источника) на источник (регистр или переменная) и помещает результат в AL, АХ или ЕАХ, а остаток — в АН, DX или EDX соответственно. Результат всегда округляется в сторону нуля, абсолютное значение остатка всегда меньше абсолютного значения делителя. Значения флагов CF, OF, SF, ZF, AF и PF после этой команды не определены, а переполнение или деление на ноль вызывает исключение #DE (ошибка при делении) в защищенном режиме и прерывание 0 — в реальном.
• Команда: INC приемник • Назначение: Инкремент • Процессор: 8086 Увеличивает приемник (регистр или переменная) на 1. В отличие от команды ADD приемник,1 не влияет на флаг CF. Остальные арифметические флаги (OF, SF, ZF, AF, PF) устанавливаются в соответствии с результатом сложения.
• Команда: DEC приемник • Назначение: Декремент • Процессор: 8086 Уменьшает приемник (регистр или переменная) на 1. В отличие от команды SUB приемник,1 не влияет на флаг CF. Остальные арифметические флаги (OF, SF, ZF, AF, PF) устанавливаются в соответствии с результатом вычитания.
• Команда: NEG приемник • Назначение: Изменение знака • Процессор: 8086 Выполняет над числом, содержащимся в приемнике (регистр или переменная), операцию дополнения до двух. Эта операция эквивалентна обращению знака операнда, если рассматривать его как число со знаком. Если приемник равен нулю, флаг CF устанавливается в 0, иначе — в 1. Остальные флаги (OF, SF, ZF, AF, PF) устанавливаются в соответствии с результатом операции. Красивый пример применения команды NEG — получение абсолютного значения числа, используя всего две команды — изменение знака и переход на первую команду еще раз, если знак отрицательный: label0: neg еах js label0
• Команда: СМР приемник,источник • Назначение: Сравнение • Процессор: 8086 Сравнивает приемник и источник и устанавливает флаги. Сравнение осуществляется путем вычитания источника (число, регистр или переменная) из приемника (регистр или переменная: приемник и источник не могут быть переменными одновременно), причем результат вычитания никуда не записывается, единственным результатом работы этой команды оказывается изменение флагов CF, OF, SF, ZF, AF и PF. Обычно команду СМР используют вместе с командами условного перехода (Jcc), условной пересылки данных (CMOVcc) или условной установки байт (SETcc), которые позволяют использовать результат сравнения, не обращая внимания на детальное значение каждого флага. Так, команды CMOVE, JE и SETE выполнят соответствующие действия, если значения операндов предшествующей команды СМР были равны. Несмотря на то что условные команды почти всегда применяются сразу после СМР, их, разумеется, можно использовать после любой команды, модифицирующей флаги, например: проверить равенство АХ нулю можно более короткой командой test ax,ax а равенство единице — однобайтной командой dec ax
• Команда: CMPXCHG приемник,источник • Назначение: Сравнить и обменять между собой • Процессор: 80486 Сравнивает значение, содержащееся в AL, AX, EAX (в зависимости от размера операндов), с приемником (регистром). Если они равны, содержимое источника копируется в приемник и флаг ZF устанавливается в 1. Если они не равны, содержимое приемника копируется в AL, АХ, EAX и флаг ZF устанавливается в 0. Остальные флаги устанавливаются по результату операции сравнения, как после СМР. Источник всегда регистр, приемник может быть регистром и переменной.
• Команда: CMPXCHG8B приемник • Назначение: Сравнить и обменять восемь байт • Процессор: Р5 Выполняет сравнение содержимого регистров EDX:EAX как 64-битного числа (младшее двойное слово в EAX, старшее — в EDX) с приемником (восьмибайтная переменная в памяти). Если они равны, содержимое регистров ЕСХ:ЕВХ как 64-бтное число (младшее двойное слово в ЕВХ, старшее — в ЕСХ) копируется в приемник. Иначе содержимое приемника копируется в EDX:EAX. Десятичная арифметика Процессоры Intel поддерживают операции с двумя форматами десятичных чисел: неупакованное двоично-десятичное число — байт, принимающий значения от 00 до 09, и упакованное двоично-десятичное число — байт, принимающий значения от 00 до 99h. Все обычные арифметические операции над такими числами приводят к неправильным результатам. Например, если увеличить 19h на 1, то получится число lAh, а не 20h. Для коррекции результатов арифметических действий над двоично-десятичными числами используются следующие команды.
• Команда: DAA • Назначение: BCD-коррекция после сложения • Процессор: 8086 Если эта команда выполняется сразу после ADD (ADC, INC или XADD) и в регистре AL находится сумма двух упакованных двоично-десятичных чисел, то в результате в AL записывается упакованное двоично-десятичное число, которое должно было быть результатом сложения. Например, если AL содержит число 19h, последовательность команд inc al daa приведет к тому, что в AL окажется 20h (а не lAh, как было бы после INC). Команда DAA выполняет следующие действия: • Если младшие четыре бита AL больше 9 или флаг AF = 1, • то AL увеличивается на 6, CF устанавливается, если при этом сложении произошел перенос, и AF устанавливается в 1. • Иначе AF = 0. • Если теперь старшие четыре бита AL больше 9 или флаг CF = 1, • то AL увеличивается на 60h и CF устанавливается в 1. • Иначе CF = 0. Флаги AF и CF устанавливаются, если в ходе коррекции происходил перенос из первой или второй цифры соответственно, SF, ZF и PF устанавливаются в соответствии с результатом, флаг OF не определен.
• Команда: DAS • Назначение: BCD-коррекция после вычитания • Процессор: 8086 Если эта команда выполняется сразу после SUB (SBB или DEC) и в регистре AL находится разность двух упакованных двоично-десятичных чисел, то в результате в AL записывается упакованное двоично-десятичное число, которое должно было быть результатом вычитания. Например, если AL содержит число 20h, последовательность команд dec al das приведет к тому, что в AL окажется 19h (а не 1Fh, как было бы после DEC). Команда DAS выполняет следующие действия: • Если младшие четыре бита AL больше 9 или флаг AF = 1, • то AL уменьшается на 6, CF устанавливается, если при этом вычитании произошел заем, и AF устанавливается в 1. • Иначе AF = 0. • Если теперь старшие четыре бита AL больше 9 или флаг CF = 1, ' то AL уменьшается на 60h и CF устанавливается в 1. • Иначе CF = 0. Известный пример необычного использования этой команды — самый компактный вариант преобразования шестнадцатеричной цифры в ASCII-код соответствующего символа (более длинный и очевидный вариант этого преобразования реализуется с помощью команды XLAT): cmp al,10 sbb al,96h das После SBB числа 0 – 9 превращаются в 96h – 9Fh, а числа 0Ah – 0Fh — в 0A1h – 0A6h. Затем DAS вычитает 66h из первой группы чисел, переводя их в 30h – 39h, и 60h из второй группы чисел, переводя их в 41h – 46h. Флаги AF и CF устанавливаются, если в ходе коррекции происходил заем из первой или второй цифры соответственно, SF, ZF и PF устанавливаются в соответствии с результатом, флаг OF не определен.
• Команда: ААА • Назначение: ASCII-коррекция после сложения • Процессор: 8086 Корректирует сумму двух неупакованных двоично-десятичных чисел в AL. Если коррекция приводит к десятичному переносу, АН увеличивается на 1. Эта команда имеет смысл сразу после команды сложения двух таких чисел. Например, если при сложении 05 и 06 в АХ окажется число 000Bh, то команда ААА скорректирует его в 0l0lh (неупакованное десятичное 11). Флаги CF и OF устанавливаются в 1, если произошел перенос из AL в АН, иначе они равны нулю. Значения флагов OF, SF, ZF и PF не определены.
• Команда: AAS • Назначение: ASCII-коррекция после вычитания • Процессор: 8086 Корректирует разность двух неупакованных двоично-десятичных чисел в AL сразу после команды SUB или SBB. Если коррекция приводит к займу, АН уменьшается на 1. Флаги CF и OF устанавливаются в 1, если произошел заем из AL в АН, и в ноль — в противном случае. Значения флагов OF, SF, ZF и PF не определены.
• Команда: ААМ • Назначение: ASCII-коррекция после умножения • Процессор: 8086 Корректирует результат умножения неупакованных двоично-десятичных чисел, находящийся в АХ после выполнения команды MUL, преобразовывая полученный результат в пару неупакованных двоично-десятичных чисел (в АН и AL). Например: mov al, 5 mov bl,5;умножить 5 на 5 mul bl;результат в АХ – 0019h aam;теперь АХ содержит 0205h ААМ устанавливает флаги SF, ZF и PF в соответствии с результатом и оставляет OF, AF и CF неопределенными. Код команды ААМ — D4h 0Ah, где 0Ah — основание системы счисления, по отношению к которой выполняется коррекция. Этот байт можно заменить на любое другое число (кроме нуля), и ААМ преобразует АХ к двум неупакованным цифрам любой системы счисления. Такая обобщенная форма ААМ работает на всех процессорах (начиная с 8086), но появляется в документации Intel только с процессоров Pentium. Фактически действие, которое выполняет ААМ, — целочисленное деление AL на 0Ah (или любое другое число в общем случае), частное помещается в AL, и остаток — в АН, так что эту команду часто используют для быстрого деления в высокооптимизированных алгоритмах.
• Команда: AAD • Назначение: ASCII-коррекция перед делением • Процессор: 8086 Выполняет коррекцию неупакованного двоично-десятичного числа, находящегося в регистре АХ, так, чтобы последующее деление привело к корректному десятичному результату. Например, разделим десятичное 25 на 5: mov ax,0205h;25 в неупакованном формате mov bl,5 aad;теперь в АХ находится 19h div bl;AX = 0005 Флаги SF, ZF и PF устанавливаются в соответствии с результатом, OF, AF и CF не определены. Так же как и команда ААМ, AAD используется с любой системой счисления: ее код — D5h 0Ah, и второй байт можно заменить на любое другое число. Действие AAD состоит в том, что содержимое регистра АН умножается на второй байт команды (0Ah по умолчанию) и складывается с AL, после чего АН обнуляется, так что AAD можно использовать для быстрого умножения на любое число. Логические операции • Команда: AND приемник,источник • Назначение: Логическое И • Процессор: 8086 Команда выполняет побитовое «логическое И» над приемником (регистр или переменная) и источником (число, регистр или переменная; источник и приемник не могут быть переменными одновременно) и помещает результат в приемник. Любой бит результата равен 1, только если соответствующие биты обоих операндов были равны 1, и равен 0 в остальных случаях. Наиболее часто AND применяют для выборочного обнуления отдельных бит, например: команда and al,00001111b обнулит старшие четыре бита регистра AL, сохранив неизменными четыре младших. Флаги OF н CF обнуляются, SF, ZF и PF устанавливаются в соответствии с результатом, AF не определен.
• Команда: OR приемник,источник • Назначение: Логическое ИЛИ • Процессор: 8086 Выполняет побитовое «логическое ИЛИ» над приемником (регистр или переменная) и источником (число, регистр или переменная; источник и приемник не могут быть переменными одновременно) и помещает результат в приемник. Любой бит результата равен 0, только если соответствующие биты обоих операндов были равны 0, и равен 1 в остальных случаях. Команду OR чаще всего используют для выборочной установки отдельных бит, например: команда or al,00001111b приведет к тому, что младшие четыре бита регистра AL будут установлены в 1. При выполнении команды OR флаги OF и CF обнуляются, SF, ZF и PF устанавливаются в соответствии с результатом, AF не определен.
• Команда: XOR приемник,источник • Назначение: Логическое исключающее ИЛИ • Процессор: 8086 Выполняет побитовое «логическое исключающее ИЛИ» над приемником (регистр или переменная) и источником (число, регистр или переменная; источник и приемник не могут быть переменными одновременно) и помещает результат в приемник. Любой бит результата равен 1, если соответствующие биты операндов различны, и нулю, если одинаковы. XOR используется для самых разных операций, например: хоr ах,ах; обнуление регистра АХ или хоr ах,bх хоr bх,ах хоr ах,bх; меняет местами содержимое АХ и ВХ Оба этих примера могут выполняться быстрее, чем соответствующие очевидные команды mov ax, 0 или xchg ax, bx
• Команда: NOT приемник • Н
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Последнее изменение этой страницы: 2016-08-15; просмотров: 821; Нарушение авторского права страницы; Мы поможем в написании вашей работы! infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 3.148.112.15 (0.013 с.) |