Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
.docx
Скачиваний:
5
Добавлен:
30.10.2018
Размер:
824.42 Кб
Скачать

15. Базові команди. Класифікація команд. Команди передачі даних. Команди обміну процесора з пам'яттю. Команди передачі кодів між процесором і периферією.

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

Большинство команд процессора вызывается с аргументами, которые в ассемблере принято называть операндами. Например: команда сложения содержимого регистра с числом требует задания двух операндов — содержимого регистра и числа.

Способы задания операндов

  1. Операнд задаётся неявно на микропрограммном уровне. В этом случае команда явно не содержит операндов. Алгоритм выполнения команды использует некоторые объекты по умолчанию (регистры, флаги). Например, команды cli и sti неявно работают с флагом прерывания if в регистре eflags, а команда xlat неявно обращается к регистру al и строке в памяти по адресу, определяемому парой регистров ds:bx.

  2. Операнд задаётся в самой команде (непосредственный операнд). Операнд находится в коде команды, то есть является её частью. Для хранения такого операнда в команде выделяется поле длиной до 32 бит. Непосредственный операнд может быть только вторым операндом (источником). Операнд получатель может находиться либо в памяти либо в регистре. Например: mov ax,0ffffh пересылает в регистр ах константу ffff. Команда add sum,2 складывает содержимое поля по адресу sum с целым числом 2 и записывает результат по месту первого операнда в память.

  3. Операнд находиться в одном из регистров. Операнд указывается именем регистра, например:

– 32 разрядные регистры EAX, EBX, ECX, EDX, ESI, EDI, ESP, EBP;

– 16 разрядные регистры AX, BX, CX, DX, SI, DI, SP, BP;

– 8 разрядные регистры AH, AL, BH, BL, CH, CL, DH, DL;

– сегментные регистры CS, DS, SS, ES, FS, GS.

Например: аdd ax,bx складывает содержимое регистров ax и bx и записывает результат в bx. Команда dec si уменьшает содержимое si на единицу.

  1. Операнд располагается в памяти. Данные способ позволяет реализовать прямую адресацию и косвенную адресацию. Косвенная адресация имеет следующие виды:

– косвенная базовая адресация (регистровая косвенная адресация);

– косвенная базовая адресация со смещением;

– косвенная индексная адресация со смещением;

– косвенная базовая индексная адресация;

– косвенная базовая индексная адресация со смещением.

  1. Операндом является порт ввода-вывода. Так как помимо адресного пространства оперативной памяти микропроцессор поддерживает адресное пространство ввода-вывода, которое используется для доступа к устройствам ввода-вывода. Объём адресного пространства ввода-вывода составляет 64 кБайт. Конкретное значение адреса в пределах этого пространства называется портом ввода-вывода. Порту ввода-вывода соответствует аппаратный регистр, доступ к которому осуществляется с помощью команд in и out. Например:

in al,60h ; ввести байт из порта 60h (прочитать скан-код клавиши. Контроллеру клавиатуры соответствуют порты от 60h 6fh. Для стандарнтых операций достаточно портов 60h 61h)

  1. Операнд находиться в стеке. Большинство команд требуют двух операндов: операнда источника и операнда назначения. В двухоперандной машинной команде возможны следующие сочетания операндов:

– регистр-регистр;

– регистр-память;

– память-регистр;

– непосредственный операнд – регистр;

– непосредственный операнд – память;

Способы адресации.

  1. Прямая адресация. Эффективный адрес операнда содержится в самой команде и для его формирования не используется дополнительных источников или регистров. Эффективный адрес (смещение) берётся из поля смещения машинной команды, которое может иметь размер 8, 16, 32 бита. Прямая адресация может быть двух типов:

1) Относительная прямая адресация. Используется для команд условных переходов, для указания относительного адреса перехода. Поле смещения машинной команды, в результате работы команды будет складываться с содержимым регистра указателя команд ip/eip. В результате такого сложения получается адрес, по которому и осуществляется переход. Например:

jc m1 ;

mov al,2

---

m1:

Ассемблер вычисляет смещение метки m1 относительно следующей команды (mov al,2) и подставляет его в формируемую машинную команду jc.

2) Абсолютная прямая адресация. При этом эффективный адрес является частью машинной команды, но формируется этот адрес только из значения поля смещения в команде. Для формирования физического адреса операнда в памяти микропроцессор складывает это поле со сдвинутым на 4 бита значением сегментного регистра. Можно использовать несколько форм такой адресации. К примеру: если операнд — слово, находящееся в сегменте, на который указывает ES, со смещением от начала сегмента 0001, то команда:

mov ax,es:0001

поместит это слово в регистр AX.

Если используемым ячейкам в программе присваиваются имена, то в процессе трансляции ассемблер вычисляет и подставляет значения смещений этих имён в формируемую им машинную команду в поле смещение в команде. В итоге получается, что машинная команда прямо адресует свой операнд, имея в одном из своих полей значение эффективного адреса. Например, если в сегменте, указанном в ES, была описана переменная word_var размером в слово, можно записать ту же команду как:

mov ax,es:word_var

В таком случае ассемблер сам заменит слово «word_var» на соответствующий адрес. Если селектор сегмента данных находится в DS, имя сегментного регистра при прямой адресации можно не указывать, DS используется по умолчанию. Прямая адресация иногда называется адресацией по смещению.

  1. Косвенная базовая (регистровая) адресация.

Адрес операнда в памяти можно не указывать непосредственно, а хранить в любом регистре. Для этого можно использовать 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]

Команда mov ax,[ecx] помещает в регистр ах содержимое слова по адресу из сегмента данных со смещением, хранящимся в регистре ecx.

При этом, DS используется по умолчанию, но не во всех случаях: если смещение берут из регистров ESP, EBP или BP, то в качестве сегментного регистра используется SS. В реальном режиме можно свободно пользоваться всеми 32-битными регистрами, надо только следить, чтобы их содержимое не превышало границ 16-битного слова.

  1. Косвенная базовая (регистровая) адресация со смещением. Этот вид адресации предназначен для доступа к данным с известным смещением относительно некоторого базового адреса. Команда:

mov ax,[bx+2]

помещает в регистр AX слово, находящееся в сегменте, указанном в DS, со смещением на 2 большим, чем число, находящееся в BX. Такая форма адресации используется в тех случаях, когда в регистре находится адрес начала структуры данных, а доступ надо осуществить к какому-нибудь элементу этой структуры. Ещё одно применение подобной адресации — доступ из подпрограммы к параметрам, переданным в стеке, используя регистр BP (EBP) в качестве базы и номер параметра в качестве смещения. Другие допустимые формы записи этого способа адресации:

mov ax,[bp]+2

mov ax,2[bp]

До 80386 в качестве базового регистра можно было использовать только BX, BP, SI или DI и сдвиг мог быть только байтом или словом (со знаком). Начиная с 80386 и старше, в качестве базового регистра можно использовать BX, BP, SI или DI, EAX, EBX, ECX, EDX, EBP, ESP, ESI и EDI.

Команда:

mov ax,[edx+3h]

пересылает в регистр ax слова из области памяти по адресу: содержимое edx+3h.

Команда:

mov ax,mas[dx]

пересылает в регистр ax слово по адресу: содержимое dx плюс значение идентификатора mas (транслятор присваивает каждому идентификатору значение, равное смещению этого идентификатора относительно начала сегмента данных).

С помощью этого метода можно организовывать доступ к одномерным массивам байт: смещение соответствует адресу начала массива, а число в регистре — индексу элемента массива, который надо считать. Если массив состоит не из байт, а из слов, необходимо умножать базовый регистр на два, а если из двойных слов — на четыре. Для этого предусмотрен следующий специальный метод адресации.

  1. Косвенная индексная адресация со смещением. Для формирования эффективного адреса используется один из регистров общего назначения. Индексная адресация связана с возможностью масштабирования содержимого индексного регистра. Таким образом можно проситать элемент массива слов, двойных слов или учетверённых слов. Например в команде

mov ax, mas[esi*2]

значение эффективного адреса второго операнда вычисляется выражением mas+(esi)*2. Множитель, который может быть равен 1, 2, 4 или 8, соответствует размеру элемента мас сива — байту, слову, двойному слову, учетверенному слову соответственно. Из регистров в этом варианте адресации можно использовать только EAX, EBX, ECX, EDX, ESI, EDI, EBP, ESP, но не SI, DI, BP или SP.

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

mov ax,[bx+si+2]

mov ax,[bx][si]+2

mov ax,[bx+2][si]

mov ax,[bx][si+2]

mov ax,2[bx][si]

В регистр AX помещается слово из ячейки памяти со смещением, равным сумме чисел, содержащихся в BX и SI, и числа 2. Из шестнадцатибитных регистров так можно складывать только BX + SI, BX + DI, BP + SI и BP + DI, а из 32-битных — все восемь регистров общего назначения. Так же как и для прямой адресации, вместо непосредственного указания числа можно использовать имя переменной, заданной одной из директив определения данных.

  1. Косвенная базовая индексная адресация со смещением. Эффективный адрес формируется как сумма трёх составляющих: содержимого базового регистра, содержимого индексного регистра и значения поля смещения в команде. Полный адрес операнда можно записать как выражение, представленное на рис. 1.

Рис. 1. Полная форма косвенной базовой индексной адресации со смещением.

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

mov eax,[esi+5][edx] ; пересылает в регистр ах двойное слово по адресу: (esi)+5+(edx).

Команда

add ax,array[esi][ebx] ; складывает содержимое регистра ах с содержимым слова по адресу: значение идентификатора array +(esi)+(ebx).

Классификация машинных команд

С появлением новых моделей микропроцессоров количество команд возрастает. Набор микрокоманд можно классифицировать по группам и подгруппам. Общая классификация системы команд микропроцессора приведена на рис. 2.

Рис. 2. Машинные команды микропроцессора до Pentium III.

Команды основного процессора

Рис. 3. Классификация целочисленных команд процессора.

Любая последовательность действий, описываемых алгоритмом может быть:

– линейной;

– нелинейной.

На линейных участках алгоритма как правило работают следующие группы команд:

– команды пересылки данных;

– арифметические команды;

– логические команды;

– команды управления состоянием процессора.

Команды пересылки данных делятся на команды:

– пересылки данных;

– ввода-вывода в порт;

– работы с адресами и указателями;

– преобразования данных;

– работы со стеком.

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

mov <операнд_назначения>, <операнд_источник>

Поддерживаются начиная с процессора 8086.

xchg <операнд1>, <операнд2>

cmovcc <приёмник><источник> – поддерживается начиная с процессора Р6

bswap <регистр 32> – поддерживается начиная с процессора 80486

Команда mov (перемещать) не перемещает, а копирует значение из источника в приёмник. Особенности применения этой команды:

1) нельзя осуществлять пересылку из одной области памяти в другую. При такой необходимости нужно использовать в качестве промежуточного буфера любой доступный регистр общего назначения. Пример: необходимо переслать байты из ячейки fls в ячейку fld:

masm

model small

.data

fls db 5

fld db ?

.code

Start

----

mov al, fls

mov fld,al

----

end start

2) нельзя загрузить в сегментный регистр значение непосредственно из памяти. Для выполнения такой загрузки нужно использовать промежуточный объект (регистр общего назначения или стек). Например, чтобы загрузить в сегментный регистр ds значение адреса сегмента, содержащееся в предопределённой переменной @data, необходимо использовать регистр общего назначения ах.

3) нельзя пересылать содержимое одного сегментного регистра в другой сегментный регистр. Выполнить такую пересылку можно, используя в качестве промежуточных регистры общего назначения. Пример: инициализировать регистр es значением регистра ds:

mov ax,ds

move es,ax

Можно также использовать стек и команды push и pop:

push ds ; поместить значение регистра ds в стек

pop es ; записать в es число из стека

4) нельзя использовать сегментный регистр cs в качестве операнда назначения.

Команда mov соответствует оператору присваивания например для языка Pascal:

операнд_назначения:= <операнд_источник>

Оба операнда команды mov должны быть одного размера. Например запись:

mov ax, bl ; неправильна.

Для копирования значения bl в регистр ax необходимо «расширить диапазон», то есть скопировать весь bx в ax, а затем загрузить 0 в ah:

mov ax,bx ; загружаем bx в ax

mov ah,0 ; «сбрасываем» верхнюю часть ах, записываем в неё 0, то есть в ah

Если же длина обоих операторов разная, то используется директива указания типа. Например:

mov ax,word ptr [bx] ; если [bx] адресует слово в памяти

inc byte ptr [bx] ; если [bx] адресует байт в памяти

decd word ptr [bx] ; если [bx] адресует двойное слово в памяти

mov word ptr [bx],0 ; если [bx] адресует слово в памяти

Оператор ptr необходимо применять и когда требуется принудительно поменять размерность операндов. К примеру, требуется переслать значение 0ffh во второй байт поля flp:

masm

model small

.data

----

.code

start:

----

mov byte ptr (flp+1),0ffh

----

end start

Для двунаправленной пересылки данных применяют команду xchg. Эту же операцию можно выполнить применив последовательность из нескольких команд mov. Общий вид записи:

XCHG <операнд1>, <операнд2>

Содержимое операнда2 копируется в операнд1, а старое содержимое операнда1 — в операнд2. XCHG можно выполнять над двумя регистрами или над регистром и переменной. Например:

xchg eax,ebx ; обменять содержимое регистров eax и ebx. То же, что три команды

; на языке С: temp = eax; eax = ebx; ebx = temp;

xchg al,al ; а эта команда не делает ничего

xchg ax, word ptr [si] ; обменять содержимое регистра ах и слова в памяти по адресу в [si]

Для условной пересылки данных используется команда:

CMOVcc <приёмник><источник>

Набор команд, которые копируют содержимое источника в приемник, если удовлетворяется то или иное условие (см. табл. 1). Источником может быть регистр общего назначения или переменная, а приемником — только регистр. Условие, которое должно удовлетворяться, — просто равенство нулю или единице тех или иных флагов из регистра FLAGS. Можно использовать команды CMOVcc сразу после команды СМР (сравнение) с теми же операндами, например:

cmp ах,bх ; сравнить ах и bх

cmovl ax,bx ; если ах < bх, скопировать bх в ах

Команды ввода-вывода

Периферийные устройства используют так называемые шлюзы ввода-вывода – обычно их называют портами ввода-вывода. С помощью портов программа или сам процессор может «общаться» с тем или иным периферийным устройством. Для того, чтобы послать в порт данные или считать из него данные достаточно двух команд микропроцессора:

in приёмник, источник – ввод в аккумулятор из порта с номером номер_порта;

out приёмник, источник – вывод содержимого аккумулятора в порт с номером номер_порта.

Команда in копирует число из порта ввода-вывода, номер которого указан в источнике, в приемник. Приемником может быть только AL, АХ или ЕАХ. Источник — или непосредственный операнд, или DX, причем можно указывать только номера портов не больше 255.

Команда out копирует число из источника (AL, АХ или ЕАХ) в порт ввода-вывода, номер которого указан в приемнике. Приемник может быть либо непосредственным номером порта, либо регистром DX. С помощью команд IN и OUT строится общение процессора с устройствами ввода-вывода — клавиатурой, жесткими дисками, различными контроллерами, а также они используются в драйверах устройств. Например, чтобы включить динамик PC, достаточно выполнить команды:

in al,61h

or al,3

out 61h,al

Команды могут in, out получать от устройства и передавать устройству порцию данных в размере байта, слова или двойного слова. Например:

in al,dx out dx,al

in ax,dx out dx,ax

in eax,dx out dx,eax

in al,imm8 out imm8,al

in ax, imm8 out imm8,ax

Команда in читает данные из порта ввода-вывода, номер которого содержится в регистре dx, и помещает результат в регистр al/ax/eax. Другие регистры, кроме al/ax/eax и dx использовать нельзя.

Команда оut отправляет данные в порт. Типы её операндов такие же, как in, но операнды указываются в обратном порядке. Ещё пример:

IN AL,15H ; загрузить в AL байт из порта 15Н

IN AX,DX ; загрузить в АХ слово из порта с номером из DX

OUT DX,AX ; аналогично, но из порта в АХ

OUT DX,AL ; загрузить байт в порт, адресуемый регистром DX

Работы с адресами и указателями

Для работы с адресами операндов, находящимися в памяти есть специальная группа команд:

lea приёмник, источник – загрузка эффективного адреса;

lds приёмник, источник – загрузка указателя в регистр сегмента данных ds;

les приёмник, источник – загрузка указателя в регистр дополнительного сегмента данных es;

lgs приёмник, источник – загрузка указателя в регистр дополнительного сегмента данных gs;

lfs приёмник, источник – загрузка указателя в регистр дополнительного сегмента данных fs;

lss приёмник, источник – загрузка указателя в регистр сегмента стека ss.

Команда lea производит пересылку не данных, а эффективного адреса данных (то есть смещения данных относительно начала сегмента данных) в регистр, указанный операндом приёмник.

Если в программе необходимо иметь полный указатель на данные (сегментную составляющую и смещение), то команды lds, les, lgs, lfs, lss позволяют получить в паре регистров полный указатель на операнд в памяти. Имя сегментного регистра, в который помещается сегментная составляющая адреса, определяется кодом операции. Смещение помещается в регистр общего назначения, указанный операндом приёмник. В командах в качестве источника нельзя указывать непосредственно имя операнда в памяти, на который необходимо получить указатель. Предварительно необходимо получить само значение полного указателя в некоторой области памяти и указать в команде получения полного адреса имя этой области. Для выполнения этого действия необходимы директивы резервирования и инициализации памяти. При применении этих директив (db, dw, dd, df, dp, dq, dt) возможен случай, когда в поле операндов указывается имя другой директивы определения данных (имя переменной). В этом случае в памяти формируется адрес этой переменной – эффективный или полный зависит от применяемой директивы. Если это dw, то в памяти формируется 16-ти битное значение эффективного адреса, если же dd – в память записывается полный адрес. Размещение этого адреса в памяти следующее: в младшем слове находится смещение, в старшем – 16-ти битная сегментная составляющая адреса.

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

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