Это старая версия документа!
Регистры
Описание и механика работы
Регистр процессора — поле заданной длины во внутрипроцессорной сверхбыстрой оперативной памяти (СОЗУ). Используется самим процессором, может быть как доступным, так и не доступным программно. Например, при выборке из памяти очередной команды она помещается в регистр команд, обращение к которому программист прописать не может.
Программно недоступные регистры: Программно недоступные регистры — любые процессорные регистры, к которым невозможно так или иначе обратиться из выполняемой программы. Пример таких регистров — это регистр команд.
Регистр команд (англ. instruction register — IR) — часть блока управления центрального процессора, содержащая инструкцию, которая выполняется в настоящий момент, или декодированную. Регистр команд — это регистр управляющего устройства компьютера. Он предназначен для хранения кода команды на период времени, который необходим для ее выполнения. Только разряд командного регистра используется для хранения кода операции: в остальных разрядах хранятся коды адресов операндов.
Программно доступные регистры есть те, к которым возможно так или иначе обратиться из выполняемой программы. Практически каждый такой регистр обозначается своим именем-идентификатором на уровне языка ассемблера и соответствующим числовым кодом-идентификатором на уровне машинного языка.
По уровню доступности программно доступные регистры неодинаковы и практически делятся на две большие подгруппы:
Системные регистры — любые регистры, программно доступные только системным программам (например, ядру операционной системы), имеющим достаточный для этого уровень системных привилегий/прав. В терминах многих машинных систем такой уровень привилегий часто называется «уровнем/режимом ядра» или «режимом супервизора».
Регистры общего назначения (РОН) — регистры, доступные любым программам. В частности, регистры, используемые без ограничения в арифметических и логических операциях, но имеющие определённые аппаратные ограничения (например, в строковых РОН). Эти регистры не характерны для эпохи мейнфреймов типа IBM/370 и стали популярными в микропроцессорах архитектуры X86 — Intel 8085, Intel 8086 и последующих.
Основные регистры и их роль
Одним из ключевых элементов архитектуры процессора являются регистры. Эти быстрые ячейки памяти, расположенные непосредственно в процессоре, играют критическую роль в выполнении программ. В этой статье мы рассмотрим:
Общие регистры.
Такие как EAX, EBX, ECX, EDX, ESP, EBP, ESI и EDI которые используются для хранения данных и выполнения операций.
Сегментные регистры.
Регистры CS, DS, SS, ES, FS, GS – управляют доступом к различным сегментам памяти.
Регистры управления и состояния.
Регистры EIP и EFLAGS, которые отслеживают и управляют потоком выполнения и состоянием процессора.
Переход на 64-битную архитектуру
С появлением архитектуры x86-64 регистры получили свои 64-битные аналоги: RAX, RBX, RCX, RDX, RSP, RBP, RSI и RDI. Расширение до 64 бит позволило увеличить объем данных, с которыми можно работать, и улучшить производительность в современных вычислительных задачах. Кроме того, в x86-64 добавлены новые регистры, такие как R8-R15, что предоставляет дополнительные возможности для оптимизации и параллельной обработки данных.
Понимание и эффективное использование этих регистров — это один из важных навыков в реверс-инжиниринге.
Разрядность регистров
Шестнадцать 64-разрядных регистров RAX, RBX, RCX, RDX, RSI, RDI, RBP, RSP, R8, R9, R10, R11, R12, R13, R14 и R15
Шестнадцать 32-разрядных регистров EAX, EBX, ECX, EDX, ESI, EDI, EBP, ESP, R8D, R9D, R10D, R11D, R12D, R13D, R14D и R15D
Шестнадцать 16-разрядных регистров AX, BX, CX, DX, SI, DI, BP, SP, R8W, R9W, R10W, R11W, R12W, R13W, R14W и R15W
Шестнадцать 8-разрядных регистров AL, AH, BL, BH, CL, CH, DL, DH, DIL, SIL, BPL, SPL, R8B, R9B, R10B, R11B, R12B, R13B, R14B и R15B
Регистры общего назначения
| Имя регистра | Описание:Обозначение | Назначение |
|---|---|---|
| EAX | Аккумулятор (Accumulator) | Арифметические и логические операций. |
| EBX | База (Base) | Применяется как указатель на данные. Используется для хранения данных и может использоваться как базовый регистр при адресации памяти. |
| ECX | Счётчик (Counter) | Хранение счетчика цикла. Используется в операциях цикла и как счетчик в командах REP и LOOP. |
| EDX | Регистр данных (Data) | Арифметические операции и операций ввода-вывода |
EAX
EAX (extended accumulator register). Часто используется для операций ввода-вывода, арифметических вычислений и хранения возвращаемых значений функций.
При расширении до 32 бит, 16-битные регистры стали частью новых 32-битных регистров. Например, регистр AX был включён в регистр EAX, где младшие 16 бит EAX соответствуют регистру AX.
При переходе к 64-битным регистрациям, 32-битные регистры (например, EAX) включены в более широкий регистр — RAX. В случае регистра RAX, младшие 32 бита этого регистра являются регистром EAX.
Таким образом, 8-битные регистры AH и AL всё также сохраняют свою функциональность и доступны в составе более широких регистров новых архитектур.
EBX
EBX (base register). Применяется как указатель на данные в сегменте данных и для хранения адресов.
Один из восьми основных регистров общего назначения в архитектуре x86 и x86-64 процессоров Intel. Это 32-битный регистр, расширенная версия 16-битного регистра BX. BX, в свою очередь, состоит из двух 8-битных регистров: BH (старший байт) и BL (младший байт).
Регистр EBX используется для хранения базового адреса, относительно которого вычисляются адреса других данных в памяти. Это может быть адрес начала структуры данных, массива или любой другой области памяти. Относительно этого адреса вычисляются смещения для доступа к конкретным элементам данных.
Доступ к элементам массива. Регистр EBX содержит адрес начала массива, ebx + 4 указывает на второй элемент массива, который загружается в EAX, ebx + 8 — на третий элемент массива, который добавляется к значению в EAX.
Работа со структурами. Регистр EBX содержит адрес структуры, используется для доступа к полям структуры: первое поле — по адресу EBX, второе поле — по адресу ebx + 2.
Индексная адресация. Регистр EBX содержит адрес начала массива, регистр ECX используется как индекс, и ebx + ecx*4 вычисляет адрес третьего элемента массива (поскольку каждый элемент занимает 4 байта). Значение третьего элемента загружается в EAX.
ECX
ECX (count register). Традиционно используется в циклах как счетчик итераций.
Один из основных регистров общего назначения в архитектуре x86 и x86-64 процессоров Intel. Это 32-битный регистр, расширенная версия 16-битного регистра CX (Count Register).
Регистр ECX состоит из двух 8-битных регистров: CH (старший байт) и CL (младший байт).
Счётчик циклов — регистр ECX часто используется как счётчик в циклах, особенно в инструкциях повторения (REP).
Указание количества сдвигов или вращений — младший байт регистра ECX (CL) используется для указания количества сдвигов или вращений в соответствующих инструкциях (например, SHL, SHR, ROL, ROR).
Передача аргументов — в некоторых соглашениях о вызовах функций (calling conventions) регистр ECX используется для передачи аргументов.
Пример использования как счётчик циклов: Регистр ECX устанавливается в 5, затем в цикле выполняются операции с элементом массива: увеличивается значение текущего элемента на 1, переходит к следующему элементу. В конце цикла ECX уменьшается на 1, и если ECX не равен нулю, управление передаётся к началу цикла.
Пример использования в сдвиговых операциях: Регистр ECX устанавливается в 4, затем значение загружается в EAX, и EAX сдвигается влево на количество бит, указанное в CL (4 бита).
Ограничения: Регистр ECX не имеет заданного наперёд типа — он может трактоваться как знаковые или беззнаковые целые числа, указатели, булевые значения и так далее. В некоторых соглашениях о вызовах регистр ECX может быть регистром scratch (call clobbered) — это означает, что он не сохраняется при вызовах функций.
EDX
EDX (data register). Дополняет eax в операциях умножения и деления, а также участвует в операциях ввода-вывода.
Регистр данных, который используется для хранения результатов промежуточных вычислений и ввода-вывода.
Арифметические операции: При умножении 32-битных чисел результат сохраняется в паре регистров EDX:EAX (старшие 32 бита в EDX, младшие — в EAX).При делении 32-битного числа на 32-битный делитель остаток записывается в EDX, а частное — в EAX.
Ввод-вывод: EDX служит для хранения адреса порта ввода-вывода в командах IN и OUT.
Соглашения о вызовах: В некоторых соглашениях (например, __fastcall) EDX используется для передачи второго параметра функции.
Логические операции: EDX может участвовать в побитовых операциях (AND, OR, XOR) и использоваться для хранения промежуточных данных.
Разделение на части: EDX можно обращаться как к 16-битному регистру DX (старшие 16 бит) и 8-битным DH (старший байт) и DL (младший байт).
Совместимость с другими регистрами: EDX часто используется в паре с EAX, особенно в 32-битных операциях.
Регистр EDX остается важным элементом в низкоуровневом программировании, обеспечивая эффективное выполнение арифметических операций и взаимодействие с аппаратными компонентами. Его гибкость и специализированные функции делают его незаменимым в ассемблерном коде.
RAX (Accumulator Register)
Используется для арифметических, логических операций и операций ввода-вывода.
64-битный регистр в архитектуре процессоров x86-64. Представляет собой расширенную версию 32-битного регистра EAX.
Структура регистра:RAX (64 бита) — основной регистр.
EAX (32 бита) — нижние 32 бита регистра RAX.
AX (16 бит) — нижние 16 бит регистра EAX.
При использовании регистра RAX меняется значение всех трёх частей, а изменение значения подрегистра влияет только на соответствующую часть большего регистра.
Регистр RAX используется для выполнения арифметических и логических операций. Также он применяется для:
Перемещения данных — RAX часто используется как операнд для различных инструкций.
Хранения возвращаемых значений — в большинстве соглашений о вызовах функций для 64-битных систем регистр RAX используется для хранения возвращаемых значений.
RBX (Base Register)
Используется для хранения данных и может использоваться как базовый регистр при адресации памяти.
RCX (Counter Register)
Используется в операциях цикла и как счетчик в командах REP и LOOP.
RDX (Data Register)
Используется в арифметических операциях, особенно в умножении и делении.
RSI (Source Index)
Используется для указания на исходный адрес при операциях с памятью (например, при копировании данных).
RDI (Destination Index)
Используется для указания на адрес назначения при операциях с памятью.
R8-R15 (Дополнительные регистры)
Введены в 64-разрядной архитектуре, используются для хранения данных и промежуточных значений.
Специальные регистры
RSP (Stack Pointer)
Указывает на вершину стека.
RBP (Base Pointer)
Используется для доступа к параметрам и локальным переменным в стеке.
CS (Code Segment)
Хранит базовый адрес сегмента кода в ОЗУ, откуда процессор считывает команды для выполнения. Если проводить аналогию между кодом и книгой, то CS указывает на номер страницы в книге (программе)
RIP (Instruction Pointer)
Указывает на следующую инструкцию, которую должен выполнить процессор. Если проводить аналогию между кодом и книгой, то RIP указывает на номер строки на странице, которая указана в CS.
FLAGS (или RFLAGS в 64-разрядной системе)
Хранит флаги состояния процессора, отражают состояние различных аспектов выполнения инструкций процессора, таких как результаты арифметических операций, наличие переноса, знак числа, флаги нуля, переполнения и др. Они предназначены для управления логикой выполнения программы, исходя из текущего состояния выполнения инструкций процессора.
Указательные и индексные регистры
| Имя регистра | Описание:Обозначение | Назначение |
|---|---|---|
| ESP | Указатель стека (Stack pointer) | Указатель на верхушку стека. Указывает на последний аргумент стека. |
| EBP | Указатель базы (Base pointer) | Указатель на базу стека внутри функции. Ссылка на аргумент локальной переменной. |
| ESI | Индекс источника (Source index) | Указатель на источник при операциях с массивом. Исполняет в инструкции по перемодуляции памяти. |
| EDI | Индекс приёмника (Destination index) | Указатель на место назначения в операциях с массивами. Исполняет в инструкции по перемодуляции памяти. |
| FLAGS,EFLAGS,RFLAGS | Регистр флагов (Flag) | Содержит биты состояния процессора |
| EIP | Указатель команд. | Указатель адреса следующей инструкции для выполнения. Не регистр а указатель на текущую функцию. |
| СS | Хранение базовых адресов (Code Segment) | Хранение базовых адресов сегмента кода в ОЗУ, откуда процессор считывает команды для выполнения. Если проводить аналогию между кодом и книгой, то CS указывает на номер страницы в книге (программе) |
| DS | (Data Segment Register) | Соответствует сегменту данных, с которыми работает процессор |
| ES | (Extra Segment Register) | Соответствует дополнительному сегменту данных |
| FS | (Additional Segment Registers) | 6-битный регистр хранения селекторов |
| GS | (Additional Segment Registers) | 6-битный регистр хранения селекторов |
| SS | (Stack Segment Register) | Соответствует сегменту стека |
| RAX | (Accumulator Register) | Арифметические, логические операций и операций ввода-вывода. |
| RBX | (Base Register) | Хранение данных и иногда используется как базовый регистр при адресации памяти. |
| AX | Младший регистр EAX. Умножение, деление, обмен с устройствами ввода/вывода (команды ввода и вывода). | |
| BX | Базовый регистр в вычислениях адреса | |
| CX | Счетчик циклов | |
| DX | Определение адреса ввода/вывода | |
| AH | high AX - старшая половина 8 бит, содержат адрес начала 64Kb сегмента, смещенный вправо на 4 бита | |
| AL | low AX — младшая половина 8 бит, содержат адрес начала 64Kb сегмента, смещенный вправо на 4 бита | |
| B, BH, BL | Младшая часть старших 16-битных регистров в архитектуре x86 | |
| SP, BP, SI, DI | 64-битный | |
| SPL, SDL, SIL, DIL | 64-битный | |
| RxD, RxW, RxB | 64-битный | |
| A | ||
| B,C,D,E,H,L | ||
| DC | 6-битный регистр хранения селекторов | |
| SP | 16-битный, содержат адрес начала 64Kb сегмента, смещенный вправо на 4 бита | |
| LDA | ||
Регистр флагов RFLAGS
| Бит | Имя | Назначение |
| 0 | CF | Флаг переноса (Carry flag):казывает, был ли при сложении перенос или заимствование при вычитании. Используется в качестве входных данных для инструкций сложения и вычитания. |
| 2 | PF | Флаг четности: устанавливается, если младшие 8 битов результата содержат четное число единиц. |
| 4 | AF | Флаг настройки: указывает, был ли при сложении перенос или заимствование при вычитании младших 4 битов. |
| 6 | ZF | Флаг нуля (Zero flag): устанавливается, если результат операции равен нулю |
| 7 | SF | Флаг знака (Sign flag): устанавливается, если результат операции отрицательный. |
| 8 | TF | Флаг прерывания выполнения (Trap flag): используется при одношаговой отладке. |
| 9 | IF | Флаг разрешения прерывания: установка этого бита разрешает аппаратные прерывания. |
| 10 | DF | Флаг направления: контролирует направление обработки. Если не установлен, то порядок от самого младшего до самого старшего адреса. Если установлен, то порядок обратный - от самого старшего до самого младшего адреса. |
| 11 | OF | Флаг переполнения (Overflow flag): если устанавлен, то операция привела к переполнению со знаком. |
| 12-13 | IOPL | Уровень привилегий ввода-вывода (I/O privilege level): уровень привилегий текущего выполняемого потока. IOPL 0 — это режим ядра, а 3 — пользовательский режим. |
| 14 | NT | Флаг вложенной задачи (Nested task flag): управляет цепочкой прерываний. |
| 16 | RF | Флаг возобновления (Resume flag): используется для обработки исключений во время отладки. |
| 17 | VM | Флаг режима виртуальной машины 8086: если установлен, режим совместимости с 8086 активен. Этот режим позволяет запускать некоторые приложения MS-DOS в контексте операционной системы в защищенном режиме. |
| 18 | AC | Флаг проверки выравнивания (Alignment check flag): если установлен, проверка выравнивания памяти активна. Например, если установлен флаг AC, сохранение 16-битного значения по нечетному адресу вызывает исключение проверки выравнивания. Процессоры x86 могут выполнять невыровненный доступ к памяти, когда этот флаг не установлен, но количество требуемых командных циклов может увеличиться. |
| 19 | VIF | Флаг виртуального прерывания (Virtual interrupt flag): виртуальная версия флага IF в виртуальном режиме 8086. |
| 20 | VIP | Флаг ожидания виртуального прерывания: Устанавливается, когда прерывание находится в состоянии ожидания в виртуальном режиме 8086. |
| 21 | ID | Флаг ID: если этот бит установлен, то поддерживается инструкция cpuid. Эта инструкция возвращает идентификатор процессора и информацию о его функциях. |
Основными являются флаги переноса, нуля, знака и переполнения, которые называют флагами состояния. Как видно, не все биты из 64-х разрядного регистра флагов имеют назначение. Неуказанные биты не используются.
В дополнение к регистрам общего назначения x86-64 предоставляет регистры специального назначения, в том числе восемь регистров для работы с числами с плавающей точкой, реализованных в модуле x87 с плавающей точкой (floating-point unit или FPU). Intel назвала эти регистры ST0 - ST7. Каждый регистр с плавающей точкой имеет ширину 80 бит. В отличие от регистров общего назначения обычная пользовательская программа не может получить к ним прямой доступ.
Также есть шестнадцать 128-битных регистров XMM (XMM0 - XMM15) и набор инструкций SSE/SSE2. Каждый регистр можно настроить как четыре 32-битных регистра с плавающей точкой; два 64-битных регистра двойной точности с плавающей точкой; или шестнадцать 8-битных, восемь 16-битных, четыре 32-битных, два 64-битных или один 128-битный целочисленный регистр. В более поздних вариантах семейства процессоров x86-64 AMD/Intel удвоили размер регистров до 256 бит каждый (переименовав их в YMM0-YMM15), добавив поддержки восьми 32-битных значений с плавающей точкой или четырех 64-битных значений с плавающей точкой двойной точности. (целочисленные операции по-прежнему ограничивались 128 битами).