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



Обработка _сdесl-подключений - часть 2


/* построениях работала chkesp. */

// Вызвать функцию, которая определяет, предназначен ли данный адрес

// для показа. После этого вызова возвращаемое значение находится в

 // ЕАХ и затем проверяется. Возврат TRUE означает выполнение функции

 // трассировки, a FALSE — пропуск функции трассировки.

 ChecklfAddressIsOn ( dwRet);

_asm MOV ESI, [dwESI] /* Восстановить ESI. */

 _asm ADD ESP, _LOCAL_SIZE /* Исключить область локальных

/* переменных. */

_asm MOV ESP, EBP /* Восстановить стандартный кадр. */

 _asm POP EBP

// Здесь и начинается функция! Четыре предшествующих строки

 // ассемблерного кода восстанавливают стек точно до того состояния,

 //в котором он был до входа в эту функцию, поэтому теперь можно 

// перейти к функции трассировки. Функция pReadDiagOutputA содержит 

// адрес функции трассировки, который я получил во время инициализации.

 _asm TEST ЕАХ, ЕАХ /* Проверить ЕАХ на 0. */

 _asm JZ IblDiagOutputA /* Если ЕАХ содержит 0, просто

/* выполнить возврат.*/ 

_asm JMP pReadDiagOutputA /* Сделано! JUMP выполняет возврат */

/* в вызывающую, а не в эту функцию. */

 IblDiagOutputA:

/* Пропущенный TRACE! Просто выполнить */

_asm RET /* возврат в вызывающую функцию. */

 }

В листинге 14-3 показана функция подключения с расширенным макросом, которая подключает функцию DiagOutputA из BUGSLAYERUTIL.DLL. Чтобы облегчить повторное использование общих подпрограмм языка ассемблера, таких как _cdeci-код пролога, в LIMODSDLL.CPP определены несколько макросов языка ассемблера (для использования в функциях подключения). Настоятельно рекомендую читателям выполнить пошаговый проход этих макросов в окне Disassembly отладчика Visual C++, чтобы наблюдать каждую инструкцию в действии.




Содержание  Назад  Вперед