Арифметика микропроцессора Intel x86
Назад | Оглавление | Дальше Новая версия документа | Форум

Регистры CPU
Память и CPU
Инструкция вычитания
Байты в регистрах CPU
Инструкция умножения
Инструкция деления

Данная тема содержит описание действий микропроцессора при выполнении элементарных математических операций. Далее, в тексте, будет использовано более краткое обозначение микропроцессора - CPU (Central Processing Unit).


Регистры CPU

Регистры – это ячейки памяти внутри CPU, в каждой из которых можно хранить одно число. Команда "R" (Register) позволяет просматривать содержимое регистров CPU:

-r <Enter>
AX=0000  BX=0000  CX=0000  DX=0000  SP=FFEE  BP=0000  SI=0000  DI=0000
DS=0ABD  ES=0ABD  SS=0ABD  CS=0ABD  IP=0100   NV UP EI PL NZ NA PO NC
0ABD:0100 048B          ADD     AL,8B

Возможно, вы увидели другие значения во второй и третьей строках листинга; эти данные имеют отношение к памяти компьютера. Различия будут сохраняться и дальше, позже мы обсудим их более подробно.

Первые четыре регистра, AX, BX, CX, DX, равны нулю. Это регистры общего назначения. Остальные регистры SP, BP, SI, DI, DS, ES, SS, CS, IP являются регистрами специального назначения.

Каждый регистр может содержать четырехразрядное шестнадцатеричное число (слово), что в двоичном представлении составляет 16 бит.

Чтобы изменить содержимое регистра AX, выполним следующую команду:

-r ax <Enter>
AX=0000
:7F9  <Enter>
Просмотрите регистры и убедитесь, что AX = 7F9:
-r
AX=07F9  BX=0000  CX=0000  DX=0000  SP=FFEE  BP=0000  SI=0000  DI=0000
DS=0ABD  ES=0ABD  SS=0ABD  CS=0ABD  IP=0100   NV UP EI PL NZ NA PO NC
0ABD:0100 048B          ADD     AL,8B

Запишите в регистры общего назначения следующие числа:

1. AX=FFFF, BX=013D, CX=1E8F, DX=05F3.
2. AX=03A7, BX=092A, CX=0000, DX=0000.

Память и CPU

В первой теме мы рассмотрели сложение двух чисел с помощью команды отладчика "H". Теперь попробуем сложить числа, используя команду микропроцессора.

Например: требуется сложить числа, хранящиеся в регистрах AX и BX. Для выполнения этой задачи, необходимо сообщить микропроцессору инструкцию. В данном случае инструкция будет состоять из двух кодов: 01h и D8h (двухбайтная инструкция).

01h (команда)   - сложить содержимое регистров
D8h (аргументы) - регистры AX и BX

Все инструкции, передаваемые микропроцессору на выполнение, должны располагаться в ОЗУ компьютера. ОЗУ - оперативное запоминающее устройство или оперативная память. В ОЗУ хранятся все исполняемые программы: Windows, MsWord, Explorer и др. Поэтому, инструкция должна быть записана в область ОЗУ, свободную от загруженных программ.

адресячейка
0000:00008A
0000:000110
0000:00021C
......
0ABD:010004
0ABD:01018B
0ABD:010200
......
FFFF:FFFD00
FFFF:FFFE00
FFFF:FFFF00

Рассмотрим структуру оперативной памяти, и определим место для хранения инструкции сложения регистров AX и BX.

ОЗУ состоит из множества упорядоченных, однобайтовых ячеек. Каждая ячейка имеет уникальный номер (адрес).

Адрес ячейки состоит из двух частей:
0ABD:0100 - полный адрес
0ABD      - сегмент
     0100 - смещение

0000:0000 - первый адрес ОЗУ
FFFF:FFFF - последний адрес ОЗУ

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

Область ОЗУ [0000:0000...0ABD:0000] заполнена различными программами, трогать данный раздел не рекомендуется. Начиная с адреса 0ABD:0100 можно писать свои инструкции. Этот адрес хранится в регистрах специального назначения CPU:

DS=0ABD, ES=0ABD, SS=0ABD, CS=0ABD и IP=0100.

Для записи в ОЗУ кодов инструкции сложения AX + BX, воспользуемся командой "E" (Edit):

-e 100 <Enter>
0ABD:0100  04.01 <Enter>
-e 101 <Enter>
0ABD:0101  8B.D8 <Enter>
Запишите в регистры следующие числа: AX = 4, BX = 3. Просмотрите регистры:
-r
AX=0004  BX=0003  CX=0000  DX=0000  SP=FFEE  BP=0000  SI=0000  DI=0000
DS=0ABD  ES=0ABD  SS=0ABD  CS=0ABD  IP=0100   NV UP EI PL NZ AC PO NC
0ABD:0100 01D8          ADD     AX,BX
В третьей строке листинга находится следующая информация:
0ABD:0100 - адрес инструкции сложения
     01D8 - коды инструкции
ADD AX,BX - мнемокод инструкции
Мнемокод служит для наглядного восприятия инструкций CPU.

Теперь все готово для выполнения операции сложения. Команда "T" (Trace) дает указание микропроцессору трассировать (выполнить) одну инструкцию:

-t
AX=0007  BX=0003  CX=0000  DX=0000  SP=FFEE  BP=0000  SI=0000  DI=0000
DS=0ABD  ES=0ABD  SS=0ABD  CS=0ABD  IP=0102   NV UP EI PL NZ AC PO NC
0ABD:0102 00E8          ADD     AL,CH

Микропроцессор выполнил сложение AX + BX и занес результат в регистр AX. Теперь в третьей строке находится адрес и мнемокод следующей инструкции. Откуда она взялась? Это фрагмент программы или данных, которые потеряли свою актуальность до загрузки Debug.

Также изменил свое значение регистр IP = 0102 (было 0100). IP (Instruction Point) - указывает на инструкцию, которую должен выполнить CPU. Верните IP в исходное состояние:

-r ip
IP=0102
:100
Вновь просмотрите регистры:
-r
AX=0007  BX=0003  CX=0000  DX=0000  SP=FFEE  BP=0000  SI=0000  DI=0000
DS=0ABD  ES=0ABD  SS=0ABD  CS=0ABD  IP=0100   NV UP EI PL NZ AC PO NC
0ABD:0100 01D8          ADD     AX,BX

Выполните трассировку, и убедитесь, что AX = 000A: 7h + 3h = Ah. Обратите внимание, что коды инструкции ADD AX, BX постоянно остаются в памяти. Для трассировки инструкции, необходимо указывать в регистре IP ее адрес (в данном случае IP = 100).

Используя инструкцию ADD, выполните следующие действия:
1. 0100 + 0F00     3. 00FF + 0001     5. 0123 + 0235
2. F03E + 01E8     4. 98A4 + 493E     6. 0E8F + 0111
(результаты вычислений можете проверить сложением в "столбик")


Инструкция вычитания

Например: требуется найти разность чисел, хранящихся в регистрах AX и BX. Эта операция выполняется двухбайтной инструкцией [29h, D8h], которая имеет мнемокод SUB AX, BX. Занесите коды инструкции в ОЗУ, по адресам 100h и 101h:

-e 100 <Enter>
0ABD:0100  01.29 <Enter>
-e 101 <Enter>
0ABD:0101  D8.D8 <Enter>

Запишите в регистры следующие числа: AX = F, BX = B, IP = 100. Просмотрите регистры:

-r
AX=000F  BX=000B  CX=0000  DX=0000  SP=FFEE  BP=0000  SI=0000  DI=0000
DS=0ABD  ES=0ABD  SS=0ABD  CS=0ABD  IP=0100   NV UP EI PL NZ AC PO NC
0ABD:0100 29D8          SUB     AX,BX
Выполните трассировку инструкции. Результат операции смотрите в регистре AX.

Используя инструкцию SUB, выполните следующие действия:
1. 012F - 012E     3. F345 - 0045     5. 0BC1 - 0AC0
2. 0983 - 0873     4. FB32 - AD8C     6. 1000 - 0001

Проверим, как CPU ведет себя с отрицательными числами. Для этого выполним вычитание 0 - 1, и посмотрим, получится ли FFFFh. Установите AX = 0, BX = 1 и выполните вычитание. Вероятно, вы получили то, что ожидали: AX = FFFFh.


Байты в регистрах CPU

В CPU находится 4 регистра общего назначения и 9 регистров специального назначения. В некоторых ситуациях регистры общего назначения делятся на два подрегистра, хранящих старший и младший байты слова. Например, регистр AX может быть представлен в виде регистра AH (старший байт) и регистра AL (младший байт).

Если AX = 3EF8, то AH = 3E и AL = F8

При делении шестнадцатибитного регистра AX на две части, получается два независимых восьмибитных регистра, в каждом из которых можно хранить один байт. По этой причине такие регистры называют байтовыми.

Существуют инструкции для работы с байтовыми регистрами, например:

ADD AH,AL (код операции: 00h, C4h)

Занесите в память компьютера коды операции сложения AH + AL:
-e 100 <Enter>
0ABD:0100  29.00 <Enter>
-e 101 <Enter>
0ABD:0101  D8.C4 <Enter>

Занесите в регистры следующие числа: AH = 01, AL = 03. К сожалению Debug не позволяет использовать команду "R" для записи чисел в регистры AH и AL, поэтому числа придется заносить парой:

-r ax
AX=0000
:0103
Установите IP = 100 и выполните трассировку. Результат сложения смотрите в регистре AH:
-t
AX=0403  BX=000B  CX=0000  DX=0000  SP=FFEE  BP=0000  SI=0000  DI=0000
DS=0ABD  ES=0ABD  SS=0ABD  CS=0ABD  IP=0102   NV UP EI PL NZ NA PO NC
0ABD:0102 00E8          ADD     AL,CH
Используя регистры AH и AL, выполните следующие действия:
1. 7F + 01     3. A4 + B5     5. 98 + 08
2. BE + 0F     4. 14 + D9     6. FF + 01

Инструкция умножения

Чтобы вычислить произведение чисел, хранящихся в регистрах AX и BX, нужно выполнить двухбайтную инструкцию [F7h, E3h], которая имеет мнемокод MUL AX, BX.

Рассмотрим умножение двух максимальных по размеру чисел, которые можно записать в регистр: FFFFh × FFFFh = FFFE0001h

Такое 32-битное число в регистр не поместится. Поэтому, результат операции умножения заносится в регистровую пару [DX:AX]: DX=FFFE, AX=0001.

Введите коды F7h и E3h по адресам 100h и 101h. Установите AX=FFFFh, BX=FFFFh и IP=100. Просмотрите регистры. В листинге регистров инструкция умножения выглядит так: MUL BX. Мнемокод инструкции не содержит регистр AX. Микропроцессор всегда умножает регистр указанный в инструкции, на регистр AX, и сохраняет результат в регистровой паре [DX:AX]. Самостоятельно завершите умножение.

Умножение чисел можно выполнять и с другими регистрами общего назначения, например: MUL CX. Но результат всегда сохраняется в регистровой паре [DX:AX].


Инструкция деления

При делении чисел микропроцессор использует сразу три регистра:

DX - старшая часть делимого
AX - младшая часть делимого
BX - делитель
=>DIV BX

Результат деления заносится в регистры AX и DX:

AX - целая часть результата
DX - остаток от деления

Например, выполним деление 7С4B12h / 100h:

  1. Поместите коды деления F7h и F3h по адресам 100h и 101h.
  2. Загрузите в регистры значения: DX=7C, AX = 4B12, BX = 100, IP = 100.
  3. Просмотрите регистры и выполните трассировку.
  4. Проверьте результаты: AX = 7С4Bh (целая часть), DX = 12h (остаток).

Используя инструкции MUL и DIV, выполните следующие действия:
1. 0FEFh x 0100h     3. 543Fh x 32CEh     5. 1000h / 0100h
2. 12E8h x 1AD7h     4. 0FE8h / 0100h     6. FFFFh / 00FFh

Назад | Оглавление | Дальше Новая версия документа | Форум