Страница 1 из 5 Программирование на ассемблере под Win32 воспринимается весьма не однозначно. Считается, что написание приложений слишком сложно для применения ассемблера. Собственно обсуждению того, насколько оправдана такая точка зрения, и посвящена данная статья. Она не ставит своей целью обучение программированию под Win32 или обучение ассемблеру, я подразумеваю, что читатели имеют определённые знания в этих областях.
В отличие от программирования под DOS, где программы написанные на языках высокого уровня (ЯВУ) были мало похожи на свои аналоги, написанные на ассемблере, приложения под Win32 имеют гораздо больше общего. В первую очередь, это связано с тем, что обращение к сервису операционной системы в Windows осуществляется посредством вызова функций, а не прерываний, что было характерно для DOS. Здесь нет передачи параметров в регистрах при обращении к сервисным функциям и, соответственно, нет и множества результирующих значений возвращаемых в регистрах общего назначения и регистре флагов. Следовательно проще запомнить и использовать протоколы вызова функций системного сервиса. С другой стороны, в Win32 нельзя непосредственно работать с аппаратным уровнем, чем "грешили" программы для DOS. Вообще написание программ под Win32 стало значительно проще и это обусловлено следующими факторами: - отсутствие startup кода, характерного для приложений и динамических библиотек написанных под Windows 3.x;
- гибкая система адресации к памяти: возможность обращаться к памяти через любой регистр общего назначения; "отсутствие" сегментных регистров;
- доступность больших объёмов виртуальной памяти;
- развитый сервис операционной системы, обилие функций, облегчающих разработку приложений;
- многообразие и доступность средств создания интерфейса с пользователем (диалоги, меню и т.п.).
Современный ассемблер, к которому относится и TASM 5.0 фирмы Borland International Inc., в свою очередь, развивал средства, которые ранее были характерны только для ЯВУ. К таким средствам можно отнести макроопределение вызова процедур, возможность введения шаблонов процедур (описание прототипов) и даже объектно-ориентированные расширения. Однако, ассемблер сохранил и такой прекрасный инструмент, как макроопределения вводимые пользователем, полноценного аналога которому нет ни в одном ЯВУ. Все эти факторы позволяют рассматривать ассемблер, как самостоятельный инструмент для написания приложений под платформы Win32 (Windows NT и Windows 95). Как иллюстрацию данного положения, рассмотрим простой пример приложения, работающего с диалоговым окном. Пример 1. Программа работы с диалогом Файл, содержащий текст приложения, dlg.asm IDEAL P586 RADIX16 MODELFLAT
%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 szAppNamedb'Demo 1', 0 szHellodb'Hello, ' szUserdbMAX_USER_NAME dup (0)
CodeSeg Start:callGetModuleHandleA,0 callDialogBoxParamA,eax, IDD_DIALOG, 0, offset DlgProc, 0 cmpeax,IDOK jnebye callMessageBoxA,0, offset szHello,\ offset szAppName,\ MB_OK or MB_ICONINFORMATION bye:callExitProcess,0
publicstdcallDlgProc procDlgProcstdcall arg@@hDlg:dword,@@iMsg:dword,@@wPar:dword,@@lPar:dword moveax,[@@iMsg] cmpeax,WM_INITDIALOG je@@init cmpeax,WM_COMMAND jne@@ret_false
moveax,[@@wPar] cmpeax,IDCANCEL je@@cancel cmpeax,IDOK jne@@ret_false
callGetDlgItemTextA,@@hDlg, IDR_NAME,\ offset szUser, MAX_USER_NAME moveax,IDOK @@cancel:callEndDialog,@@hDlg, eax
@@ret_false:xoreax,eax ret
@@init:callGetDlgItem,@@hDlg, IDR_NAME callSetFocus,eax jmp@@ret_false endpDlgProc endStart Файл ресурсов 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 коде. Теперь приложение выглядит более просто и естественно. |