<<
>>

Стартовый код

Структура нашего каркасного Windows-приложения строится в соответствии с аналогичным приложением на C/C++ (см. листинг 16.1) и его дизассемблиро- ванным вариантом (см. листинг 16.3).
Разрабатывая приложение на C/C++, мы «прячемся за спину» компилятора, доверяя ему часть работы. Программируя на ассемблере, мы лишаемся этой «широкой спины» и вынуждены всю работу делать сами. Что представляет собой эта работа, видно из листинга 16.3. Первый шаг Windows-приложения заключается в исполнении стартового кода (строки 54-73). Стартовый код представляет собой последовательный вызов функций Win32 API. Вы можете экспериментировать с ними при разработке своих программ (напри- мер, для доступа к информации о параметрах командной строки или переменных окружения), но в общем случае использовать большинство из них не обязательно. Чтобы продемонстрировать это, в листинге 16.4 вызов некоторых функций стар- тового кода закомментирован. В этой программе из всего стартового кода мы оста- вили лишь вызов функции GеtМоdulеНапdlеА (который, кстати, тоже можно за- комментировать без потери работоспособности программы). Она предназначена для идентификации исполняемого файла в адресном пространстве процесса. Здесь нужно кое-что пояснить. В литературе по платформе Win32 часто встречаются такие понятия, как про- цесс и поток. Процесс (приложение) представляет собой экземпляр программы, загруженной в память для выполнения. Процесс инертен, он просто владеет про- странством памяти в 4 Гбайт. В этом пространстве содержатся код и данные, дру- гие ресурсы, загружаемые в адресное пространство процесса. В качестве ресурсов могут быть, в свою очередь, исполняемые файлы или библиотеки DLL. Для того чтобы процесс исполнялся, в нем должен быть создан поток, который, собственно, и отвечает за исполнение кода, содержащегося в адресном пространстве процесса. Зачем такие сложности? Дело в том, что Win32 по сравнению со своими пред- шественниками кроме процессной многозадачности поддерживает еще и потоко- вую многозадачность, при которой в рамках одного процесса параллельно запус- каются несколько потоков. Таким образом, в рамках одной программы виртуально выполняются несколько фрагментов кода.
В принципе, имея несколько процессо- ров, возможно реальное распараллеливание вычислительного процесса в рамках одного приложения. Из-за того что в адресное пространство процесса можно загрузить несколько файлов, для работы с ними требуется некий механизм их однозначной идентифи- кации. При загрузке исполняемого файла (или библиотеки DLL) в адресное про- странство процесса ему присваивается уникальный номер. Этот номер передается операционной системой в качестве первого параметра hlnst (Handle Instance — описатель экземпляра) функции WiпМаiп в программе на языке C/C++. Это значе- ние используется впоследствии при вызове многих функций Win32 API, загружа- ющих те или иные ресурсы для данной программы. Что касается значения, при- сваиваемого hlnst, то оно равно базовому адресу в адресном пространстве процесса, по которому загружен данный файл с расширением .ехе. Выяснить его значение можно с помощью функции GetModuleHandle. При вызове этой функции в качестве ее единственного параметра передается адрес ASCIIZ-строки с именем исполняе- мого файла (библиотеки DLL), базовый адрес загрузки (значение hlnst) которого мы хотим получить. Если вызвать функцию GetModuleHandle, передав ей значение NULL, то мы получим значение hlnst для текущей программы, что, кстати, и делает стартовый код (см. листинг 16.3) в программе листинга 16.1. Важно отметить, что эта идентификация актуальна только в рамках одного процесса. Как правило, в системе существует по крайней мере несколько процессов, вла- деющих своим четырехгигабайтным адресным пространством и имеющих испол- няемые файлы с одинаковыми идентификаторами. Причина в том, что в Win32 адресные пространства процессов разделены, и каждый из этих процессов полага- ет, что он в системе один. Фрагмент кода с вызовом GеtМоdulеНапdlеА выглядит так: .data hiпst dd 0 .code push О call GеtМоdulеНапdlеА mov hinst, eax После этого кода вызывается главная функция приложения — WiпМаiп (см. ли- стинг 16.3).
<< | >>
Источник: В. И. Юров. Assembler. Учебник для вузов. 2-е изд. 2003

Еще по теме Стартовый код:

  1. 2. Нумерологический код
  2. Код сущности
  3. Крайон, скажи, пожалуйста, что это за код?
  4. Голосовой код
  5. Речевой код
  6. Голосовой код
  7. Речевой код
  8. Голосовой код
  9. Речевой код
  10. Голосовой код
  11. Речевой код
  12. Голосовой код
  13. Речевой код
  14. Голосовой код
  15. Речевой код
  16. Голосовой код
  17. Речевой код
  18. Голосовой код
  19. Речевой код