Стартовый код
Структура нашего каркасного Windows-приложения строится в соответствии
с аналогичным приложением на C/C++ (см. листинг 16.1) и его дизассемблиро-
вариантом (см. листинг 16.3). Разрабатывая приложение на C/C++, мы
«прячемся за спину» компилятора, доверяя ему часть работы.
на
ассемблере, мы лишаемся этой «широкой спины» и вынуждены всю работу делать
сами. Что представляет собой эта работа, видно из листинга 16.3. Первый шаг
Windows-приложения заключается в исполнении стартового кода (строки 54-73).
Стартовый код представляет собой последовательный вызов функций Win32 API.
Вы можете экспериментировать с ними при разработке своих программ (напри-
мер, для доступа к информации о параметрах командной строки или переменных
окружения), но в общем случае использовать большинство из них не обязательно.
Чтобы продемонстрировать это, в листинге 16.4 вызов некоторых функций стар-
тового кода закомментирован. В этой программе из всего стартового кода мы оста-
вили лишь вызов функции
(который, кстати, тоже можно за-
388 Глава
Создание Windows-приложений на ассемблере
комментировать без потери работоспособности программы). Она предназначена
для идентификации исполняемого файла в адресном пространстве процесса. Здесь
нужно кое-что пояснить.
В литературе по платформе Win32 часто встречаются такие понятия, как про-
цесс и поток. Процесс (приложение) представляет собой экземпляр программы,
загруженной в память для выполнения. Процесс инертен, он просто владеет про-
странством памяти в 4 Гбайт. В этом пространстве содержатся код и данные, дру-
гие ресурсы, загружаемые в адресное пространство процесса. В качестве ресурсов
могут быть, в свою очередь, исполняемые файлы или библиотеки DLL. Для того
чтобы процесс исполнялся, в нем должен быть создан поток, который, собственно,
и отвечает за исполнение кода, содержащегося в адресном пространстве процесса.
Зачем такие сложности? Дело в том, что Win32 по сравнению со своими пред-
шественниками кроме процессной многозадачности поддерживает еще и потоко-
вую многозадачность, при которой в рамках одного процесса параллельно запус-
каются несколько потоков. Таким образом, в рамках одной программы виртуально
выполняются несколько фрагментов кода. В принципе, имея несколько
ров, возможно реальное распараллеливание вычислительного процесса в рамках
одного приложения.
Из-за того что в адресное пространство процесса можно загрузить несколько
файлов, для работы с ними требуется некий механизм их однозначной идентифи-
кации. При загрузке исполняемого файла (или библиотеки DLL) в адресное про-
странство процесса ему присваивается уникальный номер. Этот номер передается
операционной системой в качестве первого параметра
(Handle Instance —
описатель экземпляра) функции
в программе на языке C/C++. Это значе-
ние используется впоследствии при вызове многих функций Win32 API, загружа-
ющих те или иные ресурсы для данной программы. Что касается значения, при-
сваиваемого hlnst, то оно равно базовому адресу в адресном пространстве процесса,
по которому загружен данный файл с расширением .ехе. Выяснить его значение
можно с помощью функции GetModuleHandle. При вызове этой функции в качестве
ее единственного параметра передается адрес ASCIIZ-строки с именем исполняе-
мого файла (библиотеки DLL), базовый адрес загрузки (значение hlnst) которого
мы хотим получить. Если вызвать функцию GetModuleHandle, передав ей значение
то мы получим значение hlnst для текущей программы, что, кстати, и делает
стартовый код (см. листинг
в программе листинга
Важно отметить, что
эта идентификация актуальна только в рамках одного процесса.
Как правило, в системе существует по крайней мере несколько процессов, вла-
деющих своим четырехгигабайтным адресным пространством и имеющих испол-
няемые файлы с одинаковыми идентификаторами. Причина в том, что в Win32
адресные пространства процессов разделены, и каждый из этих процессов полага-
ет, что он в системе один.
Фрагмент кода с вызовом
выглядит так:
0
push 0
call
mov hinst, eax
Каркасное Windows-приложение на ассемблере 389
После этого кода вызывается главная функция приложения —
(см. ли-
стинг 16.3).
Do'stlaringiz bilan baham: |