Win32asm обучение

  d8ef8794     

Первая программа


     Win32Asm Tutorial     
назад12- Первая программа вперед

12.0 - Первая программа

Пришло время создать вашу первую программу. Указания в этом уроке выделенны вот так, следуйте указаниям.

12.1 - Шаг 1

Если все хорошо, то у вас должна быть папка 'win32' (или 'win32asm') на вашем жестком диске, на том-же, что и 'masm'. Для каждого проекта вы должны создавать папку.

Создайте подпапку 'Firstprogram' в папке win32. Создайте новый текстовый файл и переименуйте его в 'first.asm'.

Важно: если вы используете ultraedit, удостоверьтесь , что установили мой 'wordfile' и переключитесь на окно 'functions' (view, views/lists, function list). Наконец, удостоверьтесь, что установили значение tab stop на 4 пробела (Advanced, configuration, Edit tab)

12.2 - Шаг 2

Поместите следующий код в first.asm:

.486
.model flat, stdcall

option casemap:none

includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib

include \masm32\include\kernel32.inc
include \masm32\include\user32.inc
include \masm32\include\windows.inc

Пока нам нужны только два dll: kernel32 и user32.

12.3 - Шаг 3

Мы собираемся сделать известную всем программу 'Hello world'. Чтобы отобразить строку 'hello world', мы будем использовать окно сообщений (messagebox). Messagebox создан, используя функцию MessageBox. Вы можете найти эту функцию в win32 справочнике программиста (см. урок 2). Вот, что там говорится:

Функция MessageBox создает, отображает, и использует окно сообщений. Окно сообщений содержит определенное приложением сообщение и заголовок, плюс любая комбинация предопределенных значков и кнопок.

int MessageBox(
HWND hWnd, // хэндл (дескриптор) окна владельца
LPCTSTR lpText, // адрес текста в окне сообщений
LPCTSTR lpCaption, // адрес заголовка окна сообщений
UINT uType // стиль окна сообщений
);

Параметры

hWndустанавливает владельца окна сообщений, которое будет создано. Если этот параметр NULL (ПУСТОЙ), окно сообщений не имеет никакого владельца.
lpTextУказывает на строку с нулевым символом в конце, содержащую сообщение, которое будет отображено.
lpCaptionУказывает на строку с нулевым символом в конце, используемую для заголовка диалогового окна. Если этот параметр NULL, используется заданный по умолчанию заголовок - ошибка.
uTypeОпределяет флаги, которые определяют содержание и поведение диалогового окна. Этот параметр может быть комбинацией флагов из следующих групп флагов.
[--Разрез--]


После этого текста следует целый список констант и флагов (которые определены в windows.inc). Я не отобразил его здесь, потому что он слишком большой. Смотрите в справочнике, вы можете увидеть, что функция MessageBox берет 4 параметра: родительское окно, указатель на строку сообщения, указатель на строку заголовка и тип messagebox.
hWnd может быть NULL, потому, что наша программа не имеет окна.
lpText Должен быть указателем на наш текст. Это значит, что этот параметр - смещение в памяти, где находится наш текст.
lpCaption смещение строки заголовка.
uType комбинация значений, описанных в справочнике, таких как MB_OK, MB_OKCANCEL, MB_ICONERROR, и т.д.
Давайте сначала определим две строки для messagebox:
Добавте это в first.asm:
.data
MsgText db "Hello world!",0
MsgTitle db "This is a messagebox",0
.data указывает на начало секции данных. Директива db непосредственно вставляет байты, а строка это набор байт, секция данных будет содержать строки выше, а чтобы они заканчивались 0, вставляем дополнительно ,0. MsgText содержит смещение первой строки, а MsgTitle смещение второй. Теперь мы можем использовать функцию:
invoke MessageBox, NULL, offset MsgText, offset MsgTitle, NULL
А так, как вы используете invoke, вы можете использовать (более безопасную) ADDR вместо offset:
invoke MessageBox, NULL, ADDR MsgText, ADDR MsgTitle, NULL
Мы еще не смотрели на последний параметр, но это прекрасно будет работать, потому что MB_OK (стиль для messagebox с кнопкой OK) равняется 0 (NULL). Но Вы можете использовать любой другой стиль. UType (4-ый параметр) определяет:
Определяет флаги, которые определяют содержание и поведение диалогового окна. Этот параметр может быть комбинацией флагов из следующих групп флагов.
Теперь возьмем для напримера, что мы хотим простой messagebox с кнопкой OK с значком 'информация'. MB_OK это стиль для кнопки OK, MB_ICONINFORMATION это стиль для информационного значка. Стили объединены с помощью оператора 'or'. Это не опкод. Masm выполнит операцию or перед ассемблированием. Вместо or, вы можете использовать знак + (добавление), но так иногда возникают проблемы с накладывающимися стилями (один стиль содержит некоторые другие). В нашем случае, вы можете использовать +.


.code
start:

invoke MessageBox, NULL, ADDR MsgText, ADDR MsgTitle, MB_OK + MB_ICONINFORMATION
end start
Добавьте вышеприведенный код к вашему файлу first.asm
Мы также добавили метку начала. Если бы вы ассемблировали сейчас нашу программу и запустили ее, она бы отобразила messagebox и вероятно повисла (или выдала ошибку) после того, как вы нажали OK. Это произойдет потому, что программа еще не закончена, и процессор начнет выполнять код, который находится после кода messagebox (а там, в данном случае, может быть всякий мусор). Программы в windows завершаются функцией ExitProcess:
Функция ExitProcess завершает процесс и все его нити.
VOID ExitProcess(
UINT uExitCode // код выхода для всех нитей
);
Мы можем использовать 0, как код выхода:
Замените ваш код на этот:
.code
start:

invoke MessageBox, NULL, ADDR MsgText, ADDR MsgTitle, MB_OK + MB_ICONINFORMATION
invoke ExitProcess, NULL
end start
12.4 - Шаг 4
Вот, та программа, которая у нас получилась:
.486
.model flat, stdcall
option casemap:none
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc
include \masm32\include\windows.inc
.data
MsgText db "Hello world!",0
MsgTitle db "This is a messagebox",0
.code
start:
invoke MessageBox, NULL, ADDR MsgText, ADDR MsgTitle, MB_OK or MB_ICONINFORMATION
invoke ExitProcess, NULL
end start
12.5 - Шаг 5
Теперь создадим исполняемую программу из этого исходного текста.
Создайте новый текстовый файл и назовите его make.bat со следующим содержанием:
@echo off
ml /c /coff first.asm
link /subsystem:windows first.obj
pause>nul
Анализ:
ml /c /coff first.asm ml это макроассемблер (masm). Masm создаст необработанный код программы. Опции означают:
/c = Ассемблирование без линковки (компоновки). (потому, что мы используем link.exe для этого)
/coff = генерировать объектный файл COFF-формата. Это стандарт для программ windows.
first.asm = ассемблируемый файл first.asm
link /subsystem:windows first.objЛинкер (компоновщик) берет объектный файл и связывает его со всеми импортированными dll и библиотеками. Опции:
/subsystem:windows = создать исполняемый файл для windows.
first.obj = Линковать first.obj

Теперь, если вы сделали все правильно и запустите файл make.bat, то здесь появится файл first.exe. Запустите его и увидите результат.
[наверх]

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