М. В. Ломоносова Факультет вычислительной математики и кибернетики В. Г. Баула Введение в архитектуру ЭВМ и системы программирования Москва 2003 Предисловие Данная книга
Вид материала | Книга |
Содержание6.8. Команды языка машины 6.8.1. Команды пересылки 6.8.2. Арифметические команды |
- М. В. Ломоносова Факультет вычислительной математики и кибернетики Кафедра математической, 6.81kb.
- Н. И. Лобачевского Факультет Вычислительной математики и кибернетики Кафедра Математического, 172.6kb.
- Н. И. Лобачевского Факультет Вычислительной Математики и Кибернетики Кафедра иисгео, 4000.54kb.
- М. В. Ломоносова факультет Вычислительной Математики и Кибернетики Диплом, 49.56kb.
- Методы интеллектуального анализа данных и некоторые их приложения, 29.22kb.
- М. В. Ломоносова Факультет Вычислительной Математики и Кибернетики Кафедра Системного, 124.67kb.
- Н. И. Лобачевского Факультет Вычислительной математики и кибернетики Кафедра Математического, 169.45kb.
- Московский Государственный Университет им. М. В. Ломоносова. Факультет Вычислительной, 104.35kb.
- М. В. Ломоносова Факультет Вычислительной Математики и Кибернетики Реферат, 170.54kb.
- М. В. Ломоносова Факультет вычислительной математики и кибернетики Руденко Т. В. Сборник, 1411.4kb.
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 div op2
AH := AX mod op2
В случае с длинными операндами при умножении вычисление производится по формуле:
(DX,AX) := AX * op2
При делении:
AX := (DX,AX) div op2
DX := (DX,AX) mod op2
В этих командах операнд 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