TURBO PASCAL |
Новости
|
Стандартный код входа и выходаКаждая процедура и функция Borland Pascal начинается и за- канчивается стандартным набором операторов, которые позволяют ак- тивизировать и деактивизировать процедуру или функцию. Стандартным входом служит следующая группа операторов: PUSH BP ; сохранить регистр ВР MOV BP,SP ; установить границы стека SUB SP,LocalSize ; выделить память для локальных пере- ; менных В этом примере LocalSize - это размер локальных переменных. Инструкция SUВ присутствует только в том случае, когда LocalSize не равно нулю. Если тип обращения к процедуре является ближним, то параметры начинаются с BP+4, если для вызова процедуры исполь- зуется дальний тип обращения, то они начинаются с BP+6. Для программ DOS код входа и выхода для подпрограммы, ис- пользующей дальнюю модель вызова, тот же, что и для подпрограммы с ближним типом вызов, но для возврата из подпрограммы использу- ется инструкция RETF. Это справедливо также для программы Windows, cкомпилированной в состоянии {$W-}. Примечание: Об использовании процедур входа и выхода в DLL рассказывается в Главе 11 "Динамически компонуемые биб- лиотеки". Стандартной группой операторов выхода является: MOV SP,BP ; освободить память, выделенную для ; локальных переменных POP BP ; восстановить регистр ВР RET ParamSize ; удалить параметры и выполнить возврат ; управления Здесь РаrамSizе - это размер параметров. Инструкция RET яв- ляется инструкцией ближнего или дальнего типа, в зависимости от типа обращения к процедуре. В состоянии {$W+} (по умолчанию) в подпрограмме, использую- щей дальнюю модель вызова, код выхода и выхода выглядит следующим образом: INC BP ; указывает на кадр стека FAR PUSH BP ; сохранить регистр ВР MOV BP,SP ; установить кадр стека PUSH DS ; сохранить DS SUB SP,LocalSize ; выделить память для локальных переменных . . . MOV SP,BP ; освободить память, выделенную для ; локальных переменных POP BP ; восстановить регистр ВР DEC PB ; настроить BP RETF ParamSize ; удалить параметры и выполнить возврат ; управления Код входа и выхода для экспортируемой подпрограммы (процедуры или функции, скомпилированной с директивой компилятора export) выглядит следующим образом: mov AXC,DS ; загрузить селектор DS в AX nop ; дополнительное пространство для ; корректировок inc BP ; указывает на дальний кадр стека push BP ; сохранить BP mov BP,SP ; установить кадр стека push DS ; сохранить DS mov DS,AX ; инициализация регистра DS sub SP,LocalSize; распределении локальных переменных . ; (если они имеются) . . pop DI ; восстановить DI pop SI ; восстановить SI lea SP,[BP-2] ; освободить память, выделенную для ; локальных переменных pop DS ; восстановить DS pop BP ; восстановить BP dec BP ; настроить регистр BP retf ParamSize ; удаление параметров и возврат ; управления Для всех моделей вызова, если подпрограмма не содержит ло- кальных переменных, инструкции выделения и освобождения памяти для локальных переменных можно опустить. При работе в реальном режиме, чтобы различать ближний и дальний кадр стека, Windows требует, чтобы все кадры стека (вклю- чая кадры стека экспортируемых подпрограмм) сохраняли в слове по адресу [BP+0] нечетное значение BP. Кроме того, Windows требует, чтобы слово по адресу [BP-2] содержало селектор сегмента данных вызывающей программы. Это объясняет использование инструкций INC BP, PUSH DS и DEC BP (сгенерированных в состоянии {$W+}) на входе и выходе для подпрограмм far и export. Заметим, что использование {$W+} требуют только реальный режим Windows. Если вы не поддерживаете реальный режим, укажите {$W-}. Вы получите программу меньшего размера и некоторый выигрыш в скорости. При разработке программы защищенного режима Windows может оказаться полезным использование состояния {$W+}. Некоторые средства отладки, отличные от средств Borland, требуют этого для корректной работы. По умолчанию Borland Pascal автоматически генерирует эффек- тивные системные вызовы для процедур и функций, экспортируемых прикладной программой. При компоновке прикладной программы в сос- тоянии {$K+} (по умолчанию) отладчик ищет в каждой экспортируемой точке входа последовательность инструкций MOV AX,DS с последующей инструкцией NOP, заменяя их на MOV AX.DS на MOV AX,SS. Это изме- нение ослабляет требование использования при создании программ системного вызова подпрограмм API Windows MakeProcInstanc и FreeProcInstance (хотя это не возбраняется). Можно также вызывать экспортируемые точки входа из самой прикладной программы. В состоянии {$K-} при создании динамически компонуемой биб- лиотеки компоновщик Borland Pascal не модифицирует код входа и выхода экспортированной точки входа. Если подпрограмма системного вызова в приложении должна вызываться из другой прикладной прог- раммы, выбирать состояние {$K-} не следует. При загрузке прикладной программы или динамически компонуе- мой библиотеки Windows ищет в каждой экспортируемой точке входа последовательность инструкций MOV AX,DS с последующей инструкцией NOP. Для прикладной программы Windows изменяет первые три байта на три инструкции NOP, чтобы подготовить подпрограмму для исполь- зования ее функцией Windows MakeProcInstance. Для библиотек Windows изменяет первые три байта в инструкции MOV AX,xxxx, где xxxx - селектор (адрес сегмента) сегмента динамических локальных данных библиотеки. |
(с)Все права защищены По всем интересующим вопросам прошу писать на электронный адрес |