Теперь, после описания точек прерывания и символьных машин, можно объяснить, как отладчики реализуют три замечательные операции — Step Into, Step Over и Step Out. Они не реализованы в WDBG, потому что я хотел сконцентрироваться на основных частях отладчика. Эти функции работают в рамках двух специальных представлений1 отлаживаемой программы, которые позволяют отслеживать текущую выполняемую строку или команду.
Все эти операции (Step Into, Step Over и Step Out) работают с одноразовыми точками прерывания, которые, как вы помните из предыдущих разделов, являются точками прерывания, сбрасываемыми отладчиком после того, как они срабатывают. При обсуждении пункта меню Debug Break (см. выше) был рассмотрен другой случай, в котором отладчик использует одноразовые точки прерывания для остановки обработки.
Операция Step Into работает по-разному, в зависимости от того, на каком уровне выполняется отладка: на исходном или на уровне дизассемблирования. При отладке на исходном уровне отладчик должен ориентироваться на одноразовые точки прерывания, потому что одна строка языка высокого уровня переводится в одну или большее количество строк языка ассемблера. При переводе CPU в пошаговый режим будет происходить пошаговое выполнение индивидуальных машинных команд, а не строк исходного кода.
На исходном уровне отладчик знает, на какой исходной строке вы находитесь. Когда выполняется команда отладчика Step Into, то для нахождения адреса следующей выполняемой строки отладчик использует символьную машину. Отладчик выполнит частичное дизассемблирование по адресу следующей строки, чтобы видеть, является ли эта строка командой вызова. Если строка — команда вызова, то отладчик установит одноразовую точку прерывания на первом же адресе функции, которую собирается вызывать подчиненный отладчик. Если адрес следующий строки — не команда вызова, то отладчик там и устанавливает точку прерывания one-shot. Затем отладчик разблокирует подчиненный отладчик, чтобы тот выполнился до только что установленной точки прерывания.