Регистры 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:0000 | 8A |
0000:0001 | 10 |
0000:0002 | 1C |
... | ... |
0ABD:0100 | 04 |
0ABD:0101 | 8B |
0ABD:0102 | 00 |
... | ... |
FFFF:FFFD | 00 |
FFFF:FFFE | 00 |
FFFF:FFFF | 00 |
Рассмотрим структуру оперативной памяти, и определим место для хранения инструкции сложения регистров 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:
- Поместите коды деления F7h и F3h по адресам 100h и 101h.
- Загрузите в регистры значения: DX=7C, AX = 4B12, BX = 100, IP = 100.
- Просмотрите регистры и выполните трассировку.
- Проверьте результаты: 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
|