вернуться к общему разделу

Регистры архитектуры IA-32

Регистр процессора — сверхбыстрая память внутри процессора, предназначенная прежде всего для хранения промежуточных результатов вычисления (регистр общего назначения/регистр данных) или содержащая данные, необходимые для работы процессора — смещения базовых таблиц, уровни доступа и т. д. (специальные регистры).
Регистр представляет собой цифровую электронную схему, служащую для временного хранения двоичных чисел. В процессоре имеется значительное количество регистров, большая часть которых используется самим процессором и недоступна программисту. Например, при выборке из памяти очередной команды она помещается в регистр команд. Программист обратиться к этому регистру не может. Имеются так же регистры, которые в принципе программно доступны, но обращение к ним осуществляется из программ операционной системы (например, управляющие регистры и теневые регистры дескрипторов сегментов). Этими регистрами пользуются в основном разработчики операционных систем.
Доступ к значениям, хранящимся в регистрах как правило в несколько раз быстрее, чем доступ к ячейкам оперативной памяти (даже если кеш-память содержит нужные данные), но объём оперативной памяти намного превосходит суммарный объём регистров (объём среднего модуля оперативной памяти сегодня составляет 1 Гб — 4 Гб[1], суммарная «ёмкость» регистров общего назначения/данных для процессора Intel 80x86 16 битов * 4 = 64 бита (8 байт)).

Основные регистры процессора, совместимого с Intel 386
IP (англ. Instruction Pointer) — регистр, обозначающий смещение следующей команды относительно кодового сегмента.
IP — 16-битный (младшая часть EIP)
EIP — 32-битный аналог
Сегментные регистры — регистры указывающие на сегменты.
CS,DS,SS,ES,FS,GS
CS — указатель на кодовый сегмент. Связка CS:IP указывает на адрес в памяти следующей команды.
Регистры данных — служат для хранения промежуточных вычислений.
RAX, RBX, RCX, RDX, RBP, RSI, RDI, RSP, R8 — R15 — 64-битные
EAX, EBX, ECX, EDX, EBP, ESI, EDI, ESP — 32-битные
AX, BX, CX, DX — 16-битные
AH, AL, BH, BL, CH, CL, DH, DL — 8-битные (половинки 16-ти битных регистров)
например, AH - high AX - старшая половинка 8 бит
AL - low AX – младшая половинка 8 бит
Регистр флагов EFLAGS — содержит текущее состояние процессора.
Регистром называется функциональный узел, осуществляющий приём, хранение и передачу информации. Регистры состоят из группы триггеров, обычно D.
По типу приёма и выдачи информации различают 2 типа регистров:
- с последовательным приёмом и выдачей информации — сдвиговые регистры.
- с параллельным приёмом и выдачей информации — параллельные регистры.
Сдвиговые регистры представляют собой последовательно соединённую цепочку триггеров. Основной режим работы — сдвиг разрядов кода от одного триггера к другому на каждый импульс тактового сигнала.
По назначению регистры различаются на:
аккумулятор — используется для хранения промежуточных результатов арифметических и логических операций и инструкций ввода-вывода;
флаговые — хранят признаки результатов арифметических и логических операций;
общего назначения — хранят операнды арифметических и логических выражений, индексы и адреса;
индексные — хранят индексы исходных и целевых элементов массива;
указательные — хранят указатели на специальные области памяти (указатель текущей операции, указатель базы, указатель стэка);
сегментные — хранят адреса и селекторы сегментов памяти;

управляющие — хранят информацию, управляющую состоянием процессора, а также адреса системных таблиц.[1]

Арифметические операции - ADD, SUB, MUL, DIV. Многие опкоды делают вычисления. Их можно узнать по названиям: add (addition - добавление), sub (substraction - вычитание), mul (multiply - умножение), div (divide - деление). Опкод add имеет следующий синтаксис:
add приемник, источник
Выполняет вычисление: приемник = приемник + источник.
Имеются также другие формы:


приемник

источник

пример

регистр

регистр

add ecx, edx

регистр

память

add ecx, dword ptr [104h] / add ecx, [edx]

регистр

значение

add eax, 102

память

значение

add dword ptr [401231h], 80

память

регистр

add dword ptr [401231h], edx

Эта команда очень проста. Она добавляет значение источника к значение приемника и помещает результат в приемник. Другие математические команды:
sub приемник, источник (приемник = приемник - источник)
mul множимое, множитель (множимое = множимое * множитель)
div делитель (eax = eax / делитель, edx = остаток)
Поскольку регистры могут содержать только целочисленные значения (то есть числа, не, с плавающей запятой), результат деления разбит на частное и остаток. Теперь, в зависимости от размера источника, частное сохраняется в eax, а остаток в edx:


размер источника

деление

частное в...

остаток в...

BYTE (8-bits)

ax / делитель

AL

AH

WORD (16-bits)

dx:ax* / делитель

AX

DX

DWORD (32-bits)

edx:eax* / делитель

EAX

EDX


* = Например: если dx = 2030h, а ax = 0040h, dx: ax = 20300040h. Dx:ax - значение dword, где dx представляет старшее word, а ax - младшее. Edx:eax - значение quadword (64 бита), где старшее dword в edx и младшее в eax.

Источник операции деления может быть:

1. 8-бит регистр (al, ah, cl,...)

2. 16-бит регистр (ax, dx, ...)

3. 32-бит регистр (eax, edx, ecx...)

4. 8-бит значение из памяти (byte ptr [xxxx])

5. 16-бит значение из памяти (word ptr [xxxx])

6. 32-бит значение памяти (dword ptr [xxxx])

Источник не может быть непосредственным значением, потому что тогда процессор не сможет определить размер исходного операнда.

Логические операции с битами - OR, XOR, AND, NOT.Эти команды работают с приемником и источником, исключение команда 'NOT'. Каждый бит в приемнике сравнивается с тем же самым битом в источнике, и в зависимости от команды, 0 или 1 помещается в бит приемника:

Команда

AND

OR

XOR

NOT

Бит источника

0

0

1

1

0

0

1

1

0

0

1

1

0

1

Бит приёмника

0

1

0

1

0

1

0

1

0

1

0

1

X

X

Бит результата

0

0

0

1

0

1

1

1

0

1

1

0

1

0

AND (логическое И) устанавливает бит результата в 1, если оба бита, бит источника и бит приемника установлены в 1. OR (логическое ИЛИ) устанавливает бит результата в 1, если один из битов, бит источника или бит приемника установлен в 1. XOR (НЕ ИЛИ) устанавливает бит результата в 1, если бит источника отличается от бита приемника. NOT инвертирует бит источника.
Пример:
mov ax, 3406d
mov dx, 13EAh
xor ax, dx
ax = 3406 (десятичное), в двоичном - 0000110101001110.
dx = 13EA (шестнадцатиричное), в двоичном - 0001001111101010. Выполнение операции XOR на этими битами:
Источник = 0001001111101010 (dx)
Приемник = 0000110101001110 (ax)
Результат = 0001111010100101 (новое значение в ax)
Новое значение в ax, после выполнения команды - 0001111010100101 (7845 - в десятичном, 1EA5 - в шестнадцатиричном).
Другой пример:
mov ecx, FFFF0000h
not ecx
FFFF0000 в двоичном это - 11111111111111110000000000000000
Если вы выполните инверсию каждого бита, то получите: 00000000000000001111111111111111 , в шестнадцатиричном это 0000FFFF Значит после операции NOT, ecx будет содержать 0000FFFFh.
Увеличение/Уменьшение - INC/DEC. Есть 2 очень простые команды, DEC и INC. Эти команды увеличивают или уменьшают содержимое памяти или регистра на единицу. Просто поместите:
inc регистр ; регистр = регистр + 1
dec регистр ; регистр = регистр - 1
inc dword ptr [103405] ; значение в [103405] будет увеличено на 1.
dec dword ptr [103405] ; значение в [103405] будет уменьшено на 1.
Ещё одна команда сравнения - test. Команда Test выполняет операцию AND (логическое И) с двумя операндами и в зависимости от результата устанавливает или сбрасывает соответствующие флаги. Результат не сохраняется. Test используется для проверки бит, например в регистре:
test eax, 100b
jnz смещение
Команда jnz выполнит переход, если в регистре eax третий бит справа - установлен. Очень часто комманду test используют для проверки, равен ли регистр нулю:
test ecx, ecx
jz смещение
Команда jz выполнит переход, если ecx = 0.
Ничего не делающая команда - nop. Эта команда не делает абсолютно ничего (пустая команда). Она только занимает пространство и время. Используется для резервирования места в сегменте кода или организации программной задержки.
Обмен значениями - XCHG. Команда XCHG также весьма проста. Назначение: обмен двух значений между регистрами или между регистрами и памятью:
mov eax , 237h
mov ecx, 978h
xchg eax, ecx
в результате:
eax = 978h
ecx = 237h [2]

ЛИТЕРАТУРА

1. Магда Ю.С. Ассемблер для  процессоров Intel Pentium. – СПб.: Питер, 2006.

2. http://ru.wikipedia.org/wiki/DLL Динамически связанные библиотеки

 

Автор: Андрей Васильев (программист)

вверх

Тематика статей

Меню