Почему пошаговая инструкция на X86? - PullRequest
6 голосов
/ 30 октября 2011

Итак, есть int 3, которая является инструкцией прерывания, используемой для точек останова в отладчиках.

Но тогда есть также "int 1", который используется для одного шага. Но зачем это нужно? Я читал, что установка флажка Trap (TF) в регистре EFLAGS позволит включить один шаг и будет ловить в ОС для каждой инструкции. Так зачем нужен отдельный тип прерывания?

Спасибо!

Ответы [ 5 ]

11 голосов
/ 30 октября 2011

int 3 - это специальное 1-байтовое прерывание.Вызов его будет прерван в отладчике, если он есть, в противном случае приложение будет аварийно завершено.

Когда отладчик устанавливает флаг прерывания, это заставляет процессор автоматически выполнять прерывание int 1 после каждой инструкции.Это позволяет отладчику выполнять пошаговые инструкции без необходимости вставлять инструкцию int 3.Вам не нужно явно вызывать это прерывание.

8 голосов
/ 30 октября 2011

Вы путаете инструкции INT и INT 3 с векторами прерываний, через которые эти инструкции будут вызываться, если инструкция была вызвана.Здесь нет одношаговой инструкции.

INT 3 (или «инструкция точки останова») вызовет отладчик, если он присутствует (или, скорее, отладчик перехватит вектор INT 3, так что, когда произойдет INT 3, будет вызван отладчик).

Если отладчик устанавливает TF (флаг трассировки), то каждая инструкция будет вызывать прерывание # 1.Это приведет к тому, что любой адрес в этом векторе прерывания будет вызван.Надеюсь, это будет одношаговая процедура отладчика.В конце концов, отладчик очистит TF, что приведет к прекращению одношаговых прерываний.

3 голосов
/ 22 марта 2016

int 3 используется для установки точки останова, чтобы код мог свободно выполняться, пока не будет достигнута определенная точка (точка останова).это ускоряет процесс отладки, поэтому нет необходимости перехватывать известный хороший код.

int 1 используется для безоговорочной остановки после каждой инструкции.это может быть удобно, когда выполняются инструкции условного перехода, а состояние флагов состояния неизвестно.в противном случае необходимо установить точку останова по адресу ветви и адресу инструкции, следующей за веткой.

int 1 is также может использоваться при вводе платы в эксплуатацию, когда и оборудование платы, и соединениеновые и непроверенные.

3 голосов
/ 30 октября 2011

Другие уже объяснили различие между инструкцией вектора прерывания 1 и int 3.

Теперь, если вам интересно, почему в обработке отладочных прерываний задействовано несколько векторов прерываний, я думаю, что это просто потому, что исходная схема 8086/8088 должна была быть относительно простой и выполнять относительно простое программное обеспечение. У него было очень мало специальных векторов прерываний, а вектор int 1 использовался только для одношаговой ловушки, и отличить его от ловушки точки останова было тривиально, по номеру вектора прерывания, то есть достаточно было просто иметь разные обработчики для векторные 1 и 3. Этот проект был перенесен на последующие процессоры x86. Более новые процессоры существенно и «быстро» расширили набор специальных векторов прерываний примерно до 20 для обработки новых исключений и расширили функциональность отладки, добавив несколько других полезных триггеров вектора 1 прерывания поверх оригинальной одношаговой ловушки (например, выборка команды , память / порт ввода / вывода, переключатель задач и т. д.). Логично было разместить большинство из них под одним и тем же вектором прерывания, поскольку они связаны и не потребляют больше векторов.

1 голос
/ 23 апреля 2019

Ниже приведены некоторые цитаты из Руководства разработчика программного обеспечения Intel Vol. 3B, глава 17:

Архитектура Intel 64 и IA-32 выделяет два прерывания векторы для обработки исключений отладки: вектор 1 ( отладка исключение, #DB) и вектор 3 ( точка останова исключение, #BP).

Для исключения :

Обработчик debug-exception обычно является программой отладчика или частью большая система программного обеспечения. Процессор генерирует исключение отладки для любое из нескольких условий . Отладчик проверяет флаги в регистрах DR6 и DR7, чтобы определить, какое условие вызвало исключение и какие другие условия могут применяться.

Для точки останова исключение:

Исключение точка останова (прерывание 3) вызвано выполнением INT 3 инструкция. Отладчики используют исключения точек останова ... как механизм приостановки выполнения программы для проверки регистров и ячейки памяти.

С процессорами Intel386 и более поздними версиями IA-32 удобнее установить точки останова с помощью регистров адреса точки останова (от DR0 до DR3). Однако исключение точки останова все еще полезно для отладчики точек останова, потому что исключение точки останова может вызвать отдельный обработчик исключений. Исключение точки останова также полезно когда необходимо установить больше точек останова, чем отладки регистры или когда точки останова помещаются в исходный код программа в разработке.

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

Только за исключением отладки, вы не сможете разбить местоположение, которое вы хотите. Только после того, как вы сломаете в каком-то месте, вы можете , а затем настроить процессор для одношаговых или других операций, которые используются исключением отладки.

INT 3 - это однобайтовый код операции. Таким образом, он может перезаписать любую существующую инструкцию с управляемым побочным эффектом, чтобы прервать выполнение текущей программы. Без этого, как вы могли бы иметь возможность установить одноступенчатый флаг в EFLAGS на соответствующее время без побочных эффектов?

Таким образом, необходим двухшаговый механизм break-and-then-debug .

Весь поток:

Сначала подключите отладчик в качестве обработчика к и int 1 (#DB) и int 3 (#BP).

Затем поместите int3 туда, где вы хотите взломать. Затем отладчик может вмешаться.

Как только отладчик начинает обрабатывать int3 (#BP), если вы хотите пошаговое выполнение, скажите отладчику установить флаг прерывания (TF) в EFLAGS. Затем CPU будет генерировать int 1 (#DB) после каждой отдельной инструкции. Так как отладчик также подключен к int 1 (#DB), у него также будет возможность подключиться.

ДОБАВИТЬ 1 - 5:55 вечера 5/31/2019

(Я обсуждал с одним из моих друзей, как работает отладчик. Он писал отладчик раньше.)

Кажется, INT 3 (#BP) - самый важный. Вы можете явно разместить инструкцию INT 3 в том месте, в которое хотите взломать. Или вы можете позволить отладчику сделать это за вас.

После нажатия INT 3 ЦПУ сохранит контекст неработающей программы и переключится на обработчик INT 3, который обычно является частью отладчика. Теперь сломанная программа приостановлена. Отладчик - это обычная Windows или любое другое настольное приложение. Он может использовать обычную настольную петлю сообщений для ожидания пользовательских команд, чтобы решить, как обращаться с отлаживаемой программой. Так что, похоже, и отладчик, и отладчик сейчас ждут. Но причины очень разные.

Затем отладчик может проверить сохраненный контекст отладчика.Или он может просто восстановить сохраненный контекст дебютанта и позволить ему возобновить.Или он может установить флаг TF в EFLAGS, чтобы процессор генерировал #DB после каждой инструкции.

Но часто , пользователи могутне хочу пошагово на уровне инструкции .Они могут захотеть отладить на уровне операторов C , который может быть , состоящим из множества команд.Таким образом, отладчик может использовать отладочную информацию, такую ​​как файл PDB, для поиска информации о местоположении.Если пользователи хотят выполнить один шаг на уровне оператора C, отладчик может найти начальную инструкцию следующего оператора C и перезаписать 1-й байт этого символа INT 3.А потом все начинается сначала.

...