Программные функции операционной системы Windows, страница 4

Хэндел – этот полу жаргонный термин означает некоторый код, которым идентифицируется тот или иной объект в операционной системе. Windows по своим «таинственным» алгоритмам вырабатывает этот код для каждого окна, рожденного в ОС. Основное окно ОС – DeskTop имеет всегда хэндел равный 0 (нулю). Причем, если мы внимательно изучим файл WINDOWS.INI, то выясним, что обозначение HWnd  имеет размер WORD. Итак установлено, что первый параметр в функции MessageBox имеет размер WORD и равен 0.

Второй и третий параметр функции – PСhar являются указателями на текстовые строки и имеют размер DWORD. Как обычно указатель составляется из двух регистров: в данном случае – селектора DS, указывающего на начало области данных в нашей программе, и смещения в области данных программы, по которому расположены строки. Поэтому второй и третий параметры функции состоят в нашем вызове ее из двух частей каждый:

ds:offset szMsg,

ds:offset szCapt, но записываются в вызове функции через запятую, что означает для компилятора поместить их перед вызовом процедуры по очереди в стек. Вообще-то вызов системной функции MessageBox (как и любой другой системной функции Windows) в тексте программы можно было бы оформить и так:

push    0                            ;разместить в стеке первый параметр (HWnd).

push    ds                          ;разместить в стеке

push    offset szMsg;второй параметр (PChar).

push    ds                          ;разместить в стеке

push    offset szCapt;третий параметр (PChar).

push    0                            ;разместить в стеке четвертый параметр (Word)

call    MESSAGEBOX;вызвать функцию поскольку, еще раз повторяю, в отличие от DOS (где функции BIOS брали необходимые им для выполнения данные из предварительно заполненных регистров процессора) в Windows все системные функции берут необходимые им для выполнения данные из СТЕКА. Поэтому перед вызовом любой системной функции Windows программист (ассемблера) должен ПРАВИЛЬНО заполнить СТЕК!

После вызова функции MessageBox на экране появляется системное окно сообщения с нашим текстом:

и программа останавливается в ожидании нажатия на кнопку ОК. Тут уместно заметить, что функция MessageBox возвращает результат нажатия кнопки в регистре AX, так что при желании проанализировать этот код надо брать его именно оттуда.

Созданное нами окно обладает всеми системными свойствами: оно перемещаемо с помощью мыши, оно имеет кнопку управления, оно имеет цвет заголовка и т.д., и все это мы сделали буквально  одним действием языка Ассемблер с помощью программы, исполняемый файл которой, как Вы увидите в последствии, имеет размер всего около 1 килобайта!

Осталось завершить программу после нажатия на кнопку ОК. Для этого используем стандартный выход из 16-ти разрядного приложения в ОС:

mov ax,4c00h

int 21h

И заканчиваем листинг программы, определяя конец сегментов программы и конец главной процедуры:

ends

end start

Теперь окончательный текст программы имеет вид:

.286

.model large, WINDOWS PASCAL

include windows.inc

extrn   MESSAGEBOX:PROC

.data

DB 16 DUP(0)

szMsg           db 'HELLO, WORLD!',0

szCapt          db 'Моя ПЕРВАЯ программа',0

.code

start:

                mov     ax, @data

                mov     ds, ax 

     call    MESSAGEBOX,0,ds,offset szMsg,ds,offset szCapt,0

                mov ax,4c00h

                int 21h

ends

end start

Для компиляции и компоновки 16-ти разрядной программы защищенного режима процессора следует использовать .BAT файл примерно следующего содержания:

tasmx  /ml /iD:\A_PAPA\TASM5\INCLUDE  MSG.asm

tlink /Twe MSG.OBJ,,,D:\A_papa\tasm5\lib\import