Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Баула.doc
Скачиваний:
112
Добавлен:
28.05.2015
Размер:
1.82 Mб
Скачать

6.8. Команды языка машины

Далее мы будем изучать синтаксис машинных команд и семантику их выполнения центральным процессором. Для удобства команды будем записывать так, как это принято в языке Ассемблер (можно считать, что мы уже начали понемногу изучать этот язык).

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

Команды пересылки – одни из самых распространённых команд в языке машины. Все они пересылают один или два байта из одного места памяти в другое. Для более компактного описания синтаксиса команд введём следующие условные обозначения:

r8 – любой короткий регистрAH,AL,BH,BL,CH,CL,DH,DL;

r16– любой из длинных регистровAX,BX,CX,DX,SI,DI,SP,BP;

m8,m16– операнды в основной памяти длиной1и2байта соответственно;

i8,i16– непосредственные операнды в самой команде длиной1и2байта соответственно;

SR– один из сегментных регистровSS,DS,ES;

m32– операнд в основной памяти длиной 4 байта.

Общий вид команды пересылки в нашей двухадресной ЭВМ такой (после точки с запятой будем записывать, как это принято в Ассемблере, комментарийк команде):

mov op1, op2; op1 := op2

Существуют следующие допустимые форматы операндов команды пересылки:

op1

оp2

R8

r8, m8, i8

R16

r16, m16, i16, SR, CS

M8

r8, i8

M16

r16, i16, SR, CS

SR

r16, m16

Команды пересылки не меняет флаги в регистре FLAGS.

6.8.2. Арифметические команды

Изучение команд для выполнения арифметических операций начнём с команд сложения и вычитания целых чисел. Определим вид и допустимые операнды у команд сложения и вычитания:

КОП op1, op2, гдеКОП=add,sub, adc,sbb.

add– сложение,

sub– вычитание:

op1 := op1  op2

adc– сложение с учётом флага переноса,

sbb– вычитание с учётом флага переноса:

op1 := op1  op2  CF

Таблица допустимых операндов для этих команд:

op1

op2

R8

r8, m8, i8

M8

r8, i8

R16

r16, m16, i16

M16

r16, i16

В результате выполнения операций изменяются флаги CF,OF,ZF,SF, которые отмечают соответственно за перенос, переполнение, нулевой результат и знак результата(флагу SF всегда присваивается знаковый бит результата). Эти команды меняют и некоторые другие флаги (см. [5,9]), но это нас интересовать не будет.

Далее рассмотрим команды умножения и деления целых чисел. Формат этих команд накладывает сильные ограничения на месторасположение операндов. Первый операнд всех команд этого класса явно в команде не указывается и находится в фиксированном регистре, принимаемом по умолчанию. В младшей модели семейства есть следующие команды умножения и деления, в них явно задаётся только второй операнд (второй сомножитель или делитель):

mul op2– беззнаковое умножение,

imul op2 – знаковое умножение,

div op2– беззнаковое целочисленное деление,

idiv op2– знаковое целочисленное деление.

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

В случае с короткими целыми операндами при умножении вычисление производится по формуле:

AX := AL * op2

При делении (операции divиmodпонимаются в смысле языка Паскаль):

AL := AX divop2

AH := AX modop2

В случае с длинными операндами при умножении вычисление производится по формуле:

(DX,AX) := AX * op2

При делении:

AX := (DX,AX) div op2

DX := (DX,AX) modop2

В этих командах операнд op2может иметь форматr8,r16,m8илиm16.

Как видим, команды умножения всегдадают точный результат, так как под хранение произведения выделяется в два раза больше места, чем под каждый из сомножителей. Команды деления могут вызывать аварийную ситуацию, если частное не помещается в отведённое для него место, т.е. в регистрыALиAXсоответственно. Заметим, что остаток от деления всегда помещается в отводимое для него место на регистрахAHилиDXсоответственно (докажите это!).

После выполнения команд умножения устанавливаются некоторые флаги, из которых для программиста представляют интерес только флаги переполнения и переноса (CFиOF). Эти флаги устанавливаются по следующему правилу.CF=OF=1, если в произведении столько значащих (двоичных) цифр, что они не помещаются в младшей половине произведения. На практике это означает, что приCF=OF=1произведение коротких целых чисел не помещается в регистрALи частично "переползает" в регистрAH, а произведение длинных целых чисел – не помещается в регистреAXи "на самом деле" занимает оба регистра (DX,AX). И наоборот, еслиCF=OF=0, то в старшей половине произведения (соответственно в регистрахAHиDX) находятся тольконезначащиедвоичные цифры произведения. Другими словами, приCF=OF=0в качестве результата произведения можно взять его младшую половину.

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

Для написания программ на Ассемблере нам будут полезны также следующие унарныеарифметические операции.

neg op1– взятие обратной величины знакового числа,op1 := -op1;

inc op1– увеличение (инкремент) аргумента на единицу,op1 := op1+1;

dec op1– уменьшение (декремент) аргумента на единицу,op1 := op1-1;

Применение этих команд вместо соответствующих по действию команд вычитания и сложения приводит к более компактным программам. Необходимо также отметить, что команды incиdec, в отличие от эквивалентных им командaddиsubникогда не меняют флагCF.1