Обучающие курсы:

Обучение профессии "Разработчик C#" + стажировка в Mail.ru
Обучение профессии "Разработчик Python" + трудоустройство
Обучение профессии "Веб-разработчик" + стажировка в Mail.ru


Главная страница
Библиотека (скачать книги)
Скачать софт
Введение в программирование
Стандарты для C++
Уроки по C#
Уроки по Python
HTML
Веб-дизайн
Ассемблер в среде Windows
ActiveX
Javascript
Общее о Линукс
Линукс - подробно
Линукс - новое
Delphi
Паскаль для начинающих
Турбопаскаль
Новости
Партнеры
Наши предложения
Архив новостей





Для компиляции и сборки такой программы при помощи макроассемблера MASM необходимо выполнить в командной строке следующую последовательность команд:
ml /с /coff hellow.asm
link /SUBSYSTEM:WINDOWS /LIBPATH: : \masm\lib hellow.obj
Опция /с компилятора mi указывает на то, что нужно создать только объектный модуль без вызова компоновщика. Опция /coff предписывает компилятору создать объектный файл в формате COFF. Компоновщик использует опцию /SUBSYSTEM:WINDOWS для генерации 32-разрядного Windows- приложения. Опция /ЫВРАТН указывает компоновщику местонахождение библиотек импорта.

Мы видим, что в исходном тексте появились новые строки:
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\include\gdi32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\gdi32.lib

Директивы includelib указывают компилятору на библиотеки импорта.
Директивы include подключают к программе файлы с расширением INC, в которых содержится важная информация. В windows.inc определены константы и структуры, используемые в программировании 32-разрядных приложений. Файлы kernel32.inc и user32.inc содержат записи о прототипах функций из системных библиотек kernel32.dll и user32.dll соответственно.
Строка записи в таком файле имеет вид:
Имя_Функции PROTO [имя_парам_1]:тип, [имя_парам_2]:тип ...
где:
• имя_Функции — идентификатор процедуры;
• [имяпарам] — необязательное имя параметра;
• тип — тип параметра.

Например, прототипы функций createwindow и Updatewindow описаны так:
ShowWindow PROTO :DWORD,:DWORD
UpdateWindow PROTO :DWORD

Каждому прототипу соответствует определенная функция в библиотеке динамической компоновки. Но возникают вопросы: зачем нужны прототипы, и что дает нам их использование? Еще раз внимательно посмотрим на листинг исходного кода. Для вызова, например, функции ShowWindow требуется выполнить последовательность команд:
push SW_SHOWNORMAL
push hWnd
call ShowWindow

Прототипы функций позволяют нам использовать так называемый высокоуровневый вызов процедур и функций при помощи выражения (оператора) invoke:
invoke <имя_функции или указатель>, [аргументы]
В этом случае вызов функции ShowWindow можно представить так:
invoke ShowWindow, hWnd, SW_SHOWNORMAL
Приведем еще один пример. Вызов функции TextOut можно представить при помощи оператора invoke следующим образом:
invoke TextOut, hdc, 100, 100, ADDR textMes, lenText

Оператор ADDR В выражении invoke для функции TextOut используется для передачи адреса переменной. Этот оператор работает только вместе с оператором invoke и самостоятельно не применяется. Однако вы можете использовать и ключевое слово offset для получения адреса переменной при работе с invoke, например:
invoke TextOut, hdc, 100, 100, offset textMes, lenText
Надо отметить, что есть одно маленькое неудобство в применении оператора ADDR: ОН не работает, если в программе имеется опережающая ссылка, т. е. если выражение invoke встретится в программе раньше, чем ссылка на переменную. В этом случае компилятор MASM выдаст ошибку. С оператором offset такого не бывает.

Остальная часть исходного текста программы состоит из рассмотренных ранее фрагментов кода и в дополнительных комментариях не нуждается. Поскольку мы довольно часто будем применять оператор invoke, то предлагается еще один вариант программы HELLOW, где большинство вызовов функций WIN API выполняется именно с помощью этого оператора (листинг 4.13).

Листинг 4.13. Вариант программы HELLOW, использующий оператор i n v o k e . HELLOW.ASM (вариант 2)
.386
.model flat, stdcaii
option casemap :none ; различаем регистр букв
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\include\gdi32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\gdi32.lib

Прототипы функций
WinMain PROTO :DWORD,:DWORD,:DWORD,:DWORD
WndProc PROTO :DWORD,:DWORD,:DWORD,:DWORD
. data
szDisplayName DB
CommandLine DD
hWnd
hlnstance
szClassName
textMes
lenText
. code
DD
DD
DB
DB
"ПЕРВОЕ ГРАФИЧЕСКОЕ ПРИЛОЖЕНИЕ HA АССЕМБЛЕРЕ",
"Demo_Class",
"ПРИВЕТ ИЗ АССЕМБЛЕРА!"
EQU $-textMes
start:
invoke GetModuleHandle, NULL
mov hlnstance, EAX
invoke GetCommandLine
mov CommandLine, EAX
invoke WinMain, hlnstance, NULL, CommandLine, SW_SHOWDEFAULT
invoke ExitProcess, 0
WinMain proc hlnst :DWORD,
hPrevInst :DWORD,
CmdLine :DWORD,
CmdShow :DWORD

; Локальные переменные процедуры
LOCAL wc :WNDCLASSEX
LOCAL msg :MSG
; Заполнение структуры WNDCLASSEX требуемыми параметрами
mov wc.cbSize, sizeof WNDCLASSEX
mov wc.style, CS_HREDRAW or CS_VREDRAW
r
mov wc.lpfnWndProc, offset WndProc
mov wc.cbClsExtra, NULL
mov wc.cbWndExtra, NULL
push hlnst
pop wc.hlnstance
mov wc.hbrBackground, C0L0R_BTNFACE+1
mov wc.IpszMenuName, NULL
mov wc.IpszClassName, offset szClassName
invoke Loadlcon, NULL, IDI_APPLICATION
mov wc.hlcon, EAX
invoke LoadCursor, NULL, IDC_ARROW
mov wc.hCursor, EAX
mov wc.hlconSm, 0
invoke RegisterClassEx, ADDR wc
invoke CreateWindowEx, WS_EX_OVERLAPPEDWINDOW, ADDR szClassName,
ADDR szDisplayName, WS_OVERLAPPEDWINDOW,\
CWJJSEDEFAULT, JJSEDEFAULT, CWJJSEDEFAULT, \
CW_USEDEFAULT, NULL, NULL, hlnst, NULL
mov hWnd, EAX
invoke ShowWindow, hWnd, SW_SHOWNORMAL
invoke Updatewindow, hWnd

; Здесь выполняется цикл обработки'сообщений
StartLoop:
invoke GetMessage, ADDR msg, NULL, 0, 0
cmp EAX, 0
je ExitLoop
invoke TranslateMessage, ADDR msg
invoke DispatchMessage, ADDR msg
jmp StartLoop
ExitLoop:
mov EAX, msg.wParam
ret
WinMain. endp

; Оконная процедура нашего приложения
WndProc proc hWin .-DWORD,
uMsg :DWORD,
wParam :DWORD,
1Param :DWORD
LOCAL hdc :HDC
LOCAL ps :PAINTSTRUCT
cmp uMsg, WM_PAINT
jne next_l
invoke BeginPaint, hWnd, ADDR ps
mov hdc, EAX
invoke TextOut, hdc, 100, 100, ADDR textMes, lenText
invoke EndPaint, hWnd, ADDR ps
ret
next_l: cmp uMsg, WM_DESTROY
j ne next_2
invoke PostQuitMessage, NULL
xor EAX, EAX
ret
next_2:
invoke DefWindowProc, hWin, uMsg, wParam, lParam
ret
WndProc endp
end start


 
 
 

Библиотека программиста. 2009.
Администратор: admin@programmer-lib.ru