Смекни!
smekni.com

Программная модель процессоров семейства X86 (стр. 3 из 9)

Система команд

Формат предложения ассемблера

[имя метки:] КОП [операнд1] [,операнд2] [;комментарии]

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

mov<операнд назначения>,<операнд-источник>
можно Нельзя Должно быть
mov ах, вх; ах:=вхmov ах,0а2h; ах:= 0а2hmov per1,ax mov ax,bhmov per1, per2mov ds,per1mov cs,dsmovcs,ax; пара cs:ip содержит адрес следующей команды mov ah, bhmov al, per2mov per1,almov ax, per1mov ds,axmov ax,ds либоpush dsmov cs,ax pop cs

xchg <операнд1>,<операнд2> ; двунаправленный обмен данными а:=в; в:=с; с:=а

xchgdl,dh; меняет местами данные


Команды ввода-вывода в порт

inаккумулятор,номер_порта — ввод в аккумулятор из порта

outпорт,аккумулятор — вывод содержимого аккумулятора в порт

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

leaназначение,источник — загрузка эффективного адреса источника в регистр-назначение;

lea dx, x ; аналогично команде movdx,offsetx

lds назначение,источник — загрузка эффективного адреса источника в регистр назначения и загрузка указателя (адрес сегмента где содержится источник) в регистр сегмента данных ds;

lesназначение,источник —-//-регистр дополнительного сегмента данных es;

lgs назначение,источник — -//- регистр дополнительного сегмента данных gs;

lfs назначение,источник — -//- регистр дополнительного сегмента данных fs;

lss назначение,источник — -//- регистр сегмента стека ss.

les dx,per1 ;полный указатель на per1 в пару es:dx

Команды работы со стеком

Для работы со стеком предназначены три регистра:

ss — сегментный регистр стека;

sp/esp — регистр указателя стека;

bp/ebp — регистр указателя базы кадра стека.

push источник — запись значения источник в вершину стека.


Алгоритм работы:

· уменьшить значение указателя стека esp/sp на 4/2 (в зависимости от значения атрибута размера адреса — use16 или use32);

· записать источник в вершину стека (адресуемую парой ss:esp/sp).

Размер записываемых значений — слово или двойное слово. Также в стек можно записывать непосредственные значения. В стек можно класть значение сегментного регистра cs. Другой интересный момент связан с регистром sp. Команда push esp/sp записывает в стек значение esp/sp по состоянию до выдачи этой команды

Команда push используется совместно с командой pop для записи значений в стек и извлечения их из стека

pop назначение — запись значения из вершины стека по месту, указанному операндом назначение. Значение при этом “снимается” с вершины стека.


Pushax

Pushbx

push cx

pop cx

pop bx

pop ax

push ax

pop bx ; аналогичнокоманде mov bx,ax

pusha - размещение в стеке регистров общего назначения в следующей последовательности: ax, cx, dx, bx, sp, bp, si, di

pushad- размещение в стеке регистров общего назначения в следующей последовательности: eax, ecx, edx, ebx, esp, ebp, esi, edi

pushf - размещение в вершине стека (ss:sp) содержимого регистра флагов flags

pushfd - размещение в стеке содержимого регистра флагов eflags.

popa- извлечение из стека регистров общего назначения di, si, bp, sp, bx, dx, cx, ax

popad - извлечение из стека регистров общего назначения edi, esi, ebp, esp, ebx, edx, ecx, eax

popf - извлечение из стека слова и восстановление его в регистр флагов flags

popfd - извлечение из стека двойного слова и восстановление его в регистр флагов eflags

Организация вычислений

Логические команды

Любая логическая команда меняет значение следующих флагов of, sf,zf,pf,cf (переполнение, знак, нуля, паритет, перенос)

and операнд_1,операнд_2 — операция логического умножения (И - конъюнкция).

оп1:=оп1 ٧оп2

and ah, 0a1h; ah:=ah٧0ah

and bx, cx; bx:=bx٧cx

and dx, x1; dx:=dx٧x1

orоперанд_1,операнд_2 — операция логического сложения (ИЛИ - дизъюнкцию)

or al, x1; оп1:=оп1 & оп2

or eax,edx

or dx, x1

xor операнд_1,операнд_2 — операция логического исключающего сложения (исключающего ИЛИ ИЛИ-НЕ)

testоперанд_1,операнд_2 — операция “проверить” (способом логического умножения).

Команда выполняет поразрядно логическую операцию И над битами операндов операнд_1 и операнд_2. Состояние операндов остается прежним, изменяются только флаги zf, sf, и pf, что дает возможность анализировать состояние отдельных битов операнда без изменения их состояния.

not операнд — операция логического отрицания. Команда выполняет поразрядное инвертирование (замену значения на обратное) каждого бита операнда. Результат записывается на место операнда.

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

model small.stack 100h.datax1 db 0c2hx2 db 022hy db ?.codestart:mov ax,@data mov ds,ax mov al, x1or al, x2mov y, al mov ax,4c00hint 21h

endstart

Арифметические операции над целыми двоичными числами

Сложение двоичных чисел без знака

incоперанд - операция инкремента, то есть увеличения значения операнда на 1;

inc ax; ax:=ax+1

inc x1

addоп1,оп2 - команда сложения с принципом действия: оп1 = оп1 + оп2 (addition)

add al, bl

add ax, 0fe2h

add ebx, x1+2

add x1, 0fh

addx2, ax

adcоп1,оп2 - команда сложения с учетом флага переноса cf. оп1 = оп1 + оп2 + знач_cf

Вычитание двоичных чисел без знака

decоперанд — операция декремента, то есть уменьшения значения операнда на 1;

dec cx ;cx:=cx-1

dec x

subоперанд_1,операнд_2 — команда вычитания; ее принцип действия:

операнд_1 = операнд_1 – операнд_2

subal, bl; al:=al-bl

sub ax, x1

sub x2, dx

sub eax, 0f35h

sub x2, 22h

sbbоперанд_1,операнд_2 — команда вычитания с учетом заема (флага cf ):

операнд_1 = операнд_1 – операнд_2 – значение_cf

Пример программы сложения двух однобайтных чисел.

model small.stack 100h.datax1 db 0c2hx2 db 022hy db ?.codestart:mov ax,@data mov ds,ax mov al, x1 add al, x2 mov y, al mov ax,4c00h int 21h

endstart

Умножение двоичных чисел

mulмножитель_1 - операция умножения двух целых чисел без учета знака

Алгоритм работы:

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

muldl; ax:=al*dl, dl- множитель_1 , al- множитель_2

mulx1; dx:ax=ax*0ad91h, x1 word- множитель_1 , ax- множитель_2

mulecx; edx:eax=eax*ecx, ecx- множитель_1 , eax- множитель_2

imul множитель_1 - операция умножения двух целочисленных двоичных значений со знаком

Деление двоичных чисел

divделитель - выполнение операции деления двух двоичных беззнаковых значений

Алгоритм работы:

Для команды необходимо задание двух операндов — делимого и делителя. Делимое задается неявно и размер его зависит от размера делителя, который указывается в команде

divdl ;ah:al=ax/dl, ax –делимое, dl- делитель , ah-частное, al -остаток

divx1 ;ax:dx=dx:ax/0ad91h, dx:ax –делимое, x1 word- делитель , ax-частное,

;dx -остаток

divecx ;eax:edx=edx:eax/ecx, edx:eax –делимое, ecx- делитель , eax-частное,

;edx -остаток

idivделитель - операция деления двух двоичных значений со знаком

Пример программы умножения двух однобайтных чисел.

model small.stack 100h.datax1 db 78yl db ?yh db ?.codestart:mov ax,@data mov ds,ax xor ax, ax mov al, 25 mulx1jncm1 ;если нет переполненияmov yh,ahm1: mov yl, al mov ax,4c00h int 21h

end start


Пример. Вычислите следующее выражение у=(х2-х3)/х1, х1,х2,х3 - однобайтные числа

model small

.stack 100h

.data

s1 db 'Введитех1',10,13,'$'

s2 db 'Введите х2',10,13,'$'

s3 db 'Введите х3',10,13,'$'

x1 db ?

x2 db ?

ycdb ? ;частное

yo db ? ;остаток

.code

start:

mov ax,@data

mov ds,ax


mov ah,09h

mov dx, offset s1

int 21h ;вывод строки

movah,01h вводим х1

int 21h ;вводим число

subal,30h ;al:=x1

mov x1,al


mov ah,09h

mov dx, offset s2

int 21h

movah,01h вводим х2

int 21h

sub al,30h ;al:=x2

mov x2,al

mov ah,09h

mov dx, offset s3

int 21h

mov ah,01h вводимх3

int 21h

sub al,30h ;al:=x3


mov bl,x2 ;bl:=x2

sub bl,al ;bl:=x2-x3

xchg al,bl ;al:=bl, al:=x2-x3

xor ah,ah ;ax:=x2-x3 вычисляему

mov dl,x1 ;dl:=x1

div dl ;ax/dl, ax/x1

mov yc,ah

mov yo,al

; можно вывести результат на экран

movax,4c00h

int 21h

end start

Командысдвига

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

Все команды сдвига устанавливают флаг переноса cf.

shlоперанд,счетчик_сдвигов (ShiftLogicalLeft) - логический сдвиг влево. Содержимое операнда сдвигается влево на количество битов, определяемое значением счетчик_сдвигов. Справа (в позицию младшего бита) вписываются нули;

shrоперанд,счетчик_сдвигов — логический сдвиг вправо.

Алгоритм работы команд:

· очередной “выдвигаемый” бит устанавливает флаг cf;

· бит, вводимый в операнд с другого конца, имеет значение 0;

· при сдвиге очередного бита он переходит во флаг cf, при этом значение предыдущего сдвинутого бита теряется!