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


Формат инструкции и адресация памяти - часть 2


Часто встречается обращение, которому предшествует спецификатор размера указателя, дифференцирующий размеры обращений к памяти. Размеры указателя специфицируются как BYTE PTR, WORD PTR и DWORD PTR (для ссылок размером в байт, слово и двойное слово, соответственно). Можно также представлять их, как приведение типов в C++. Если дизассемблер не указывает размера указателя, то он принимается равным двойному слову.

Иногда применяется прямое обращение к памяти в инструкции, т. е. в нем можно видеть непосредственный адрес соответствующего участка памяти. Например, обращение [ЕВХ] — это просто адрес памяти, содержащийся в регистре ЕВХ, и, чтобы просмотреть его содержимое (т. е. содержащийся в нем адрес), можно просто открыть окно Memory и ввести значение ЕВХ. Однако в других случаях невозможно вычислить ссылку без выполнения сложного шестнадцатеричного умножения. К счастью, окно Registers показывает, на какую память собирается сослаться инструкция.

Обратите внимание на строку "0012F988 = 0012F9D4" в нижней части рис. 6.1, отображающую эффективный адрес. Текущая инструкция (располагающаяся в данном случае по адресу Ox5F42D8B8) ссылается на адрес Ox0012F988 (левая сторона строки). Правая часть строки — это значение Ox0012F9D4, располагающееся по адресу Ox0012F988. Эффективный адрес в окне Registers показывают только те инструкции, которые выполняют обращение к памяти. Поскольку CPU x86 допускают лишь один операнд с обращением к памяти, то, прослеживая эффективный адрес, можно увидеть, к какой ячейке памяти вы собираетесь выполнить доступ и какое значение в ней расположено.

Если доступ к памяти неправомерен, то CPU генерирует исключение (типа "General Protection Fault (GPF — общая ошибка защиты)" или "ошибка страницы"). GPF указывает, что приложение пыталось получить доступ к памяти, к которой оно доступа не имело. Ошибка страницы свидетельствует о попытке получить доступ к позиции памяти, которой не существует. Просматривая строку ассемблера, на которой происходит аварийный останов, обратите внимание на ту ее часть, где находится ссылка на память.Из нее можно узнать, какие значения были недействительными. Например, если этот ссылочный операнд выглядит как [ЕАХ], то нужно просмотреть значение регистра ЕАХ в окне Registers. Если ЕАХ содержит недействительный адрес, необходимо стартовать обратное сканирование листинга ассемблера, чтобы увидеть, какая инструкция устанавливает в ЕАХ неправильное значение. Учтите, для того чтобы найти эту инструкцию, может потребоваться обратный проход через несколько вызовов. Далее (в разделе "Окна Memory и Disassembly" этой главы) показано, как можно пройти стек вручную.

 




Начало  Назад  Вперед



Книжный магазин