Создание VxD на Visual C++ без ассемблерных модулей

       

Функции, вызываемые извне


Некоторые внутренние процедуры VxD, оформленные в виде функций C++, должны вызываться системой (callback). К ним относятся, например, диспетчер системных сообщений, обработчики сервисных функций, прерываний, событий и т.п. Соглашения о связях в таких вызовах часто рассчитаны на использование языка ассемблера, когда параметры передаются в регистрах, а результат возвращается в регистрах и/или флагах процессора. В таком случае стандартное оформление функции, принятое в C++, может стать существенной помехой.

Расширение Visual C++ содержит квалификатор __declspec (naked), помещение которого в заголовке определяемой функции запрещает генерацию пролога/эпилога функции — начальной (сохранение регистров, установка указателя кадра) и завершающей (восстановление регистров, команда возврата) последовательностей команд. Результат компиляции будет содержать только код, присутствующий в теле функции в явном виде. Это позволяет программисту выполнить нужные действия в необходимой последовательности, однако налагает требования по соблюдению внутренних правил языка. В частности, должны быть сохранены регистры EBX, ESI, EDI, EBP; при использовании параметров в такой функции должен быть явно установлен указатель кадра в регистре EBP, а при использовании локальных переменных — зарезервировано достаточное количество байтов в стеке.

Для возврата из naked — функции в ее тело должна быть явно помещена команда _asm ret, если только функция не использует средств вроде VxDJmp, которые сами выполняют возврат в функцию, из которой был сделан вызов.



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