Отладка приложений

       

Регистры


Именно через регистры передается приложению каждый бит данных, который оно обрабатывает, и знание роли каждого регистра поможет вам распознать неудачный участок кода. CPU x86 имеют восемь регистров общего назначения (ЕАХ, ЕВХ, ЕСХ, EDX, ESI, EDI, ESP и ЕВР), шесть сегментных регистров (CS, DS, ES, SS, FS и GS), указатель инструкций (команд) EIP и регистр флагов (EFLAGS). Есть и другие регистры, такие как регистры отладки и управляющие машинные регистры, но это регистры специального назначения, и вы не встретитесь с ними при нормальной отладке в режиме пользователя. Все регистры общего назначения, перечисленные в табл. 6.1, являются 32-разрядными. Заметьте, что некоторые из них допускают мнемонические обозначения для доступа к различным частям полного 32-разрядного регистра. Единственный сегментный регистр, представляющий интерес для данной главы, — это регистр FS, который содержит блок информации потока (TIB), содержащий описание текущего выполняемого потока. Используются и другие сегментные регистры, но операционная система конфигурирует их таким образом, что они оказываются прозрачными по отношению к нормальной операции. Указатель инструкции содержит адрес текущей выполняющийся инструкции.

Таблица 6.1. Регистры общего назначения

32-разрядный регистр



16-разрядный доступ

Доступ к младшему байту (биты 0-7)

Доступ к старшему байту (биты 8-1 5)

Специфика использования

ЕАХ

АХ

AL

АН

Здесь хранятся возвращаемые значения целых функций

ЕВХ

ВХ

BL

ВН

Здесь хранится базовый адрес объекта в памяти

ЕСХ

СХ

CL

СН

Эти регистры используются счетчиками инструкций циклов

EDX

DX

DL

DH

Здесь хранятся 32 старших бита 64-битных значений

ESI

SI

Здесь хранится исходный адрес инструкций перемещения или сравнения в памяти

EDI

DI

Здесь хранится целевой адрес инструкций перемещения или сравнения в памяти

ESP

SP

Указатель стека. Этот регистр изменяется неявно при вызове функции, возврате из функции, отведении места в стеке для локальных переменных и очистке стека


EBP

ВР





Указатель база/кадр. Этот регистр содержит адрес стекового кадра для процедуры

Регистр флагов EFLAGS содержит флажки состояний и флажки управления. Биты EFLAGS устанавливаются различными инструкциями, чтобы указать результат их выполнения. Например, бит ZF (Zero Flag — нулевой флажок) равен 1, если результатом выполнения инструкции является нуль (0). В главе 4 описан перевод CPU в пошаговый режим (single-step mode), который включал установку бита TF (Trap Rag— флажок трассировки) в регистре EFLAGS. На рис. 6.1 приведено окно регистров Registers отладчика Visual C++. Окно Registers показывает регистр EFLAGS как EFL. Заметьте, что регистры с плавающей точкой в окне Registers не отображены. Их можно скрыть щелчком правой кнопки мыши в окне Registers и сбросом пункта Floating-Point Registers в раскрывшемся контекстном меню.

В табл. 6.2 описаны флажки, показанные в окне Registers. К сожалению, документация Visual C++ не раскрывает значения этих флажков, а мнемоника, применяемая для них в системе Visual C++, не соответствует мнемонике Intel, так что при ссылках на документацию Intel нужна соответствующая трансляция.

Рис. 6.1. Окно Registers из Visual C++

С окном Registers связана одна незначительная особенность: при обновлении флажков цвет значения регистра EFL не изменяется (в отличие от обычных регистров, значения которых при обновлениях выделяются другим цветом). Но необходимость просматривать индивидуальные значения флажков возникает довольно редко. Для облегчения разметки изменяющихся флажков можно сделать следующее: нажать кнопку New Text File (в панели Standard) и открыть новый временный файл. Затем скопировать (в буфер обмена) существующие флажки из окна Registers и вставить их в окно временного текста, чтобы сравнить их значения до и после изменения.

Таблица 6.2. Значения флажков окна Registers

Флажок окна Registers

Значение

Мнемоника в руководстве Intel

Примечания

OV

Overflow Flag (флажок переполнения)

OF

Устанавливается в 1, если операция закончилось целым переполнением или потерей значимости

UP

Direction Flag (флажок направления)

DF

Устанавливается в 1, если строчная инструкция выполняет обработку в направлении от самого высокого до самого низкого адреса (автодекремент). 0 означает, что строчная инструкция выполняет обработку в противоположном направлении: от самого низкого до самого высокого адреса (автоприращение)

El

Interrupt Enable Flag (флажок разрешения прерываний)

IF

Устанавливается в 1, если прерывания разрешены. Этот флажок будет всегда включен (1) в пользовательском режиме отладчика

PL

Sign Flag (флажок знака)

SF

Отображает самый старший (знаковый) бит результата инструкции. Устанавливается в 0 для положительных значений или в 1 — для отрицательных

ZR

Zero Flag (нулевой флажок)

ZF

Устанавливается в 1, если результатом инструкции является 0 (нуль). Этот флажок важен для инструкций сравнения

AC

Auxiliary Carry Flag (вспомогательный флажок переноса)

AF

Устанавливается в 1, если двоично-десятичная (BCD) операция генерирует служебный перенос или заем старшего разряда

PE

Parity Flag ' (флажок четности)

PF

Устанавливается в 1, если наименее значимый (младший) байт результата содержит четное число бит, установленных в 1

CY

Carry Flag (флажок переноса)

CF

Устанавливается в 1, если арифметическая операция генерирует перенос или заем из наиболее значащего (знакового) бита результата. Устанавливается в 1 также при переполнении в операциях целочисленной арифметики без знака

Еще одно важное свойство окна Registers — в нем можно редактировать значения регистров. Для этого нужно поместить курсор на первую цифру изменяемого числа (справа от знака равенства для соответствующего регистра) и ввести новое значение.



Содержание раздела