Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
SP_MET_1.DOC
Скачиваний:
2
Добавлен:
25.08.2019
Размер:
595.97 Кб
Скачать

2.2.7. Адресация по базе с индексированием

В этом методе адресации смещение операнда в памяти вычисляется как сумма чисел, содержащихся в двух регистрах, и смещения, если оно ука­зано. Все следующие команды — это разные формы записи одного и того же действия:

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, приведенные ко­манды прочитают слово, состоящее из седьмого и восьмого байт тре­тьей строки. Если таблица состоит не из одиночных байт, а из слов или двойных слов, удобнее использовать следующую, наиболее полную форму адресации.

2.2.8. Адресация по базе с индексированием и масштабированием

Это самая полная возможная схема адресации, в которую входят все случаи, рассмотренные ранее, как частные. Полный адрес операнда мож­но записать как выражение, представленное на рисунке 6.

CS:

SS:

DS:

ES:

FS:

GS:

EAX

EBX

ECX

EDX

EBP

ESP

EDI

ESI

+

EAX

EBX

ECX

EDX

EBP

EDI

ESI

1

2

4

8

+ смещение

Рис. 6. Полная форма адресации

Смещение может быть байтом или двойным словом. Если ESP или ЕВР используются в роли базового регистра, селектор сегмента операн­да берется по умолчанию из регистра SS, во всех остальных случаях из DS.

2.3. Основные непривилегированные команды

В этой главе описаны все непривилегированные команды процессоров Intel серии х86, исключая команды расширений для работы с числами повышенной точности (NPX и MMX). Для каждой команды указа­на форма записи, название и модель процессоров Intel, начиная с кото­рой она поддерживается: 8086, 80186, 80286, 80386, 80486, Р5 (Pentium), Р6 (Pentium Pro и Pentium II).

2.3.1. Пересылка данных

Команды пересылки данных осуществляют условный или безусловный обмен данными между регистрами и ячейками памяти, в том числе стековой, а также ввод и вывод данных через порты устройств.

Команда: MOV приемник,источник

• Назначение: Пересылка данных

• Процессор: 8086

Базовая команда пересылки данных. Копирует содержимое источни­ка в приемник, источник не изменяется. Команда MOV действует ана­логично операторам присваивания из языков высокого уровня, то есть команда

mov dx, bx

эквивалентна выражению

ax:=bx;

языка Паскаль или

ах=bх;

языка С, за исключением того, что команда ассемблера позволяет ра­ботать не только с переменными в памяти, но и со всеми регистрами процессора.

В качестве источника для MOV могут использоваться: число (непос­редственный операнд), регистр общего назначения, сегментный регистр или переменная (то есть операнд, находящийся в памяти). В качестве приемника — регистр общего назначения, сегментный регистр (кроме CS) или переменная. Оба операнда должны быть одного и того же раз­мера — байт, слово или двойное слово.

Нельзя выполнять пересылку данных с помощью MOV из одной пере­менной в другую, из одного сегментного регистра в другой и нельзя поме­щать в сегментный регистр непосредственный операнд — эти операции выполняют двумя командами MOV (из сегментного регистра в обычный и уже из него в другой сегментный) или парой команд PUSH/POP.

Загрузка регистра SS командой MOV автоматически запрещает прерыва­ния до окончания следующей за этим команды MOV, так что можно загру­зить SS и ESP двумя последовательными командами MOV, не опасаясь, что в этот момент произойдет прерывание, обработчик которого получит не­правильный стек. В любом случае для загрузки значения в регистр SS предпочтительнее команда LSS.

Команда: CMOVcc приемник,источник

• Назначение: Условная пересылка данных

• Процессор: Р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

Код команды

Реальное условие

Условие для СМР

CMOVA

CMOVNBE

СР = 0 и ZF = 0

если выше

если не ниже или равно

CMOVAE CMOVNB CMOVNC

CF = 0

если выше или равно

если не ниже

если нет переноса

CMOVB

CMOVNAE CMOVC

CF = 1

если ниже

если не выше или равно

если перенос

CMOVBE CMOVNA

CF = 1 и ZF = 1

если ниже или равно

если не выше

CMOVE

CMOVZ

ZF = 1

если равно

если ноль

CMOVG CMOVNLE

ZF = 0 и SF = OF

если больше

если не меньше или равно

CMOVGE CMOVNL

SF = OF

если больше или равно

если не меньше

CMOVL

CMOVNGE

SF <> OF

если меньше

если не больше или равно

CMOVLE CMOVNG

ZF = 1и SF<> OF

если меньше или равно

если не больше

CMOVNE CMOVNZ

ZF = 0

если не равно

если не ноль

CMOVNO

OF = 0

если нет переполнения

CMOVO

OF = 1

если есть переполнение

CMOVNP CMOVPO

PF = 0

если нет четности

если нечетное

CMOVP

CMOVPE

PF = 1

если есть четность

если четное

CMOVNS

SF = 0

если нет знака

CMOVS

SF = 1

если есть знак

Чтобы обратить порядок байт в 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, и не изменяют флаги).

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]