DOSUG CZ– розовая кнопка на сайте!
Logo

Программирование на ассемблере под Windows
(Александр Усов)

   Программирование на ассемблере под Win32 воспринимается весьма неоднозначно. Считается, что написание приложений слишком сложно для применения ассемблера. Собственно обсуждению того насколько оправдана такая точка зрения и посвящена данная статья. Она не ставит своей целью обучение программированию под Win32 или обучение ассемблеру, я подразумеваю, что читатели имеют определённые знания в этих областях.
   В отличие от программирования под DOS, где программы написанные на языках высокого уровня (ЯВУ) были мало похожи на свои аналоги, написанные на ассемблере, приложения под Win32 имеют гораздо больше общего. В первую очередь, это связано с тем, что обращение к сервису операционной системы в Windows осуществляется посредством вызова функций, а не прерываний, что было характерно для DOS. Здесь нет передачи параметров в регистрах при обращении к сервисным функциям и, соответственно, нет и множества результирующих значений возвращаемых в регистрах общего назначения и регистре флагов. Следовательно проще запомнить и использовать протоколы вызова функций системного сервиса. С другой стороны, в Win32 нельзя непосредственно работать с аппаратным уровнем, чем "грешили" программы для DOS. Вообще написание программ под Win32 стало значительно проще и это обусловлено следующими факторами:
 - отсутствие startup кода, характерного для приложений и динамических библиотек написанных под Windows 3.x;
 - гибкая система адресации к памяти: возможность обращаться к памяти через любой регистр общего назначения; "отсутствие" сегментных регистров;
 - доступность больших объёмов виртуальной памяти;
 - развитый сервис операционной системы, обилие функций, облегчающих разработку приложений;
 - многообразие и доступность средств создания интерфейса с пользователем (диалоги, меню и т.п.).
   Современный ассемблер, к которому относится и TASM 5.0 фирмы Borland International Inc., в свою очередь, развивал средства, которые ранее были характерны только для ЯВУ. К таким средствам можно отнести макроопределение вызова процедур, возможность введения шаблонов процедур (описание прототипов) и даже объектно-ориентированные расширения. Однако, ассемблер сохранил и такой прекрасный инструмент, как макроопределения, вводимые пользователем, полноценного аналога которому нет ни в одном ЯВУ.
Все эти факторы позволяют рассматривать ассемблер, как самостоятельный инструмент для написания приложений под платформы Win32 (Windows NT и Windows 95). Как иллюстрацию данного положения, рассмотрим простой пример приложения, работающего с диалоговым окном.

; ----------------- dlg.asm

IDEAL
P586
RADIX 16
MODEL FLAT

%NOINCL
%NOLIST
include "winconst.inc" ; API Win32 consts
include "winptype.inc" ; API Win32 functions prototype
include "winprocs.inc" ; API Win32 function
include "resource.inc" ; resource consts

MAX_USER_NAME = 20
DataSeg
szAppName db 'Demo 1', 0
szHello db 'Hello, '
szUser db MAX_USER_NAME dup (0)

CodeSeg
Start: call GetModuleHandleA, 0
call DialogBoxParamA, eax, IDD_DIALOG, 0, offset DlgProc, 0
cmp eax,IDOK
jne bye
call MessageBoxA, 0, offset szHello, \
      offset szAppName, \
      MB_OK or MB_ICONINFORMATION
bye: call ExitProcess, 0

public stdcall DlgProc
proc DlgProc stdcall
arg @@hDlg :dword, @@iMsg :dword, @@wPar :dword, @@lPar :dword
mov eax,[@@iMsg]
cmp eax,WM_INITDIALOG
je @@init
cmp eax,WM_COMMAND
jne @@ret_false

mov eax,[@@wPar]
cmp eax,IDCANCEL
je @@cancel
cmp eax,IDOK
jne @@ret_false

call GetDlgItemTextA, @@hDlg, IDR_NAME, \
      offset szUser, MAX_USER_NAME
mov eax,IDOK
@@cancel: call EndDialog, @@hDlg, eax

@@ret_false: xor eax,eax
ret

@@init: call GetDlgItem, @@hDlg, IDR_NAME
call SetFocus, eax
jmp @@ret_false
endp DlgProc
end Start

; ---------------- dlg.rc
#include "resource.h"
IDD_DIALOG DIALOGEX 0, 0, 187, 95
STYLE DS_MODALFRAME | DS_3DLOOK | WS_POPUP | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_CLIENTEDGE
CAPTION "Dialog"
FONT 8, "MS Sans Serif"
BEGIN
DEFPUSHBUTTON "OK",IDOK,134,76,50,14
PUSHBUTTON "Cancel",IDCANCEL,73,76,50,14
LTEXT "Type your name",IDC_STATIC,4,36,52,8
EDITTEXT IDR_NAME,72,32,112,14,ES_AUTOHSCROLL
END

   Остальные файлы из данного примера, приведены в приложении 1.
   Краткие комментарии к программе:
   Сразу после метки Start, программа обращается к функции API Win32 GetModuleHandle для получения handle данного модуля (данный параметр чаще именуют как handle of instance). Получив handle, мы вызываем диалог, созданный либо вручную, либо с помощью какой-либо программы построителя ресурсов. Далее программа проверяет результат работы диалогового окна. Если пользователь вышел из диалога посредством нажатия клавиши OK, то приложение запускает MessageBox с текстом приветствия.
   Диалоговая процедура обрабатывает следующие сообщения: при инициализации диалога (WM_INITDIALOG) она просит Windows установить фокус на поле ввода имени пользователя. Сообщение WM_COMMAND обрабатывается в таком порядке: делается проверка на код нажатия клавиши. Если была нажата клавиша OK, то пользовательский ввод копируется в переменную szValue, если же была нажата клавиша Cancel, то копирования не производится. Но и в том и другом случае вызывается функция окончания диалога: EndDialog. Остальные сообщения в группе WM_COMMAND просто игнорируются, предоставляя Windows действовать по умолчанию.
   Вы можете сравнить приведённую программу с аналогичной программой, написанной на ЯВУ, разница в написании будет незначительна. Очевидно те, кто писал приложения на ассемблере под Windows 3.x, отметят тот факт, что исчезла необходимость в сложном и громоздком startup коде. Теперь приложение выглядит более просто и естественно.

 
главная - о проекте - контакты - реклама на сайте
 
LBN100 Elite

SoftStudio.Ru - студия разработки программ
LBN100 Elite