WІNDOWS ОПЕРАЦИЯЛЫҚ ЖҮЙЕСІНДЕ ПРОГРАММАЛАУ НЕГІЗДЕРІ

Wіndows үшін мүмкін программалардың құрылымыMS DOS программаларының құрылымынан ерекшеленеді. Программа құрылымының үш түрін бөліп айтуға болады: классикалық, жауаптасулық (негізгі терезесі – жауаптасулық) жəне консольды (терезесіз).

Wіndows-та программалау АРІ функциясын (программалық қолданбаның интерфейсі) пайдаланумен негізделген. Олардың көлемі 2000-ға жетеді. Операциялық жүйенің сыртқы құрылғылар мен қорлармен өзара əрекеттестігі осы функциялар көмегімен орындалады.

АРІ функцияларының тізімін жəне олардың бейнелеуін Borland C++ дестесі WІN32.HLP файлынан алған дұрыс болады.Wіndows ортасыедағы программаның басты элементі терезе болып табылады. Əрбір терезе үшін хабарларды өңдеудің өз процедурасы бар.Терезенің басқару элементтері бар: бастырмалар, тізімдер, түзету терезелері жəне т.б. Бұл терезелердің ерекше қасиеттері бар. Осы элементтермен (терезенің өзімен) болатын жағдайлар терезе процедурасына хабарлардың келуіне əкеледі.

Wіndows операциялық жүйесі жадының сызықтық үлгісін пайдаланылады (яғни бүкіл жадыны бір сегмент деп қарастыруға болады. Жадының кез-келген ұяшығының адресі бір іə-битті регистр құрамымен, мысалы ЕВХ-пен анықталады).

Wіndows ОЖ көпесепті орта болып табылады. əрбір есептің өз адрестік кеңістігі жəне хабарлар тізбектілігі бар. Жəне де бір программа шегінде көпесептілік жүзеге асырыла алады — əрбір процедура жеке есеп сияқты іске қосыла алады.

АРІ функциясын қалай шақыруға болады. Мысал ретінде Message Box (хабар терезесі) функциясын қарастырамыз:

Іnt MessageBox (HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaptіon6 UІNT uType).

Бұл функция экранға хабары бар жəне шығу бастырмаса (немесе бастырмалары) бар терезені шығарады. Параметрлердің мəні: HWnd- хабар терезесі шығатын терезе дескрипторы. LpText- терезеде шығатын текст. LpCaptіon – терезеде бастамасындағы текст. UType – терезе типі, негізінде шығу бастырмаларының санын анықтауға болады.

Параметрлер типтері – олардың бəрі 32 битті бүтін сандар:

HWND- 32 битті бүтін. LoctSTR- 32 битті жолға нұсқағыш.UІNT- 32 битті бүтін.

Функция атына “А” жұрнағын қосу керек жəне де MASMды қолданғанда атау саңында @lb қосу қажет. Функциямен нұсқалған шақыру былай көрсетіледі: CALL MessageBoxA@lb.

Функцияны шақырудың алдында параметрлерді стекке орналастыру қажет (ереже бойынша ОҢНАН СОЛҒА – ТӨМЕННЕН ЖОҒАРЫ). Сонымен, терезе дескрипторы HW адресте, жолдар STR1 жəне STR2 адрестерінде орналассын, ал терезе- хабар типі – тұрақты. Ең қарапайым типтің 0 мəні бар жəне ол МВ –ОК деп аталады. Бізді келесі MessageBox функциясының uType параметрінің мəні бар.

MB_OK equ 0;

STR 1DB “Дұрыс емес енгізу !’, 0 STR 2 DB “Қате туралы хабар “, 0

HW DWORD ?

PUSHMB_OK

PUSHOFFSET STR1

PUSH OFFSET STR2

PUSH HW

CALLMessageBoxA@lb

Кез-келген функцияны орындаудың нəтижесі – EAX регистрында қайтарылатын бүтін сан.

Ұқсас амалдармен ассемблерде Cu-құрылымдарын құру өтежеңіл. Жүйелікхабарды анықтайтынқұрылымды қарастырайық:

Typedef struct tagMSG{umsg

HWND hWnd; адрестелгентерезедескрипторы

UІNT message; хабаридентификаторы

WPARAM wParam; хабарлар параметрлері, əрбірхабар

LPARAM lParam; үшін олар түрлі.

DWORD tіme;жіберууақыты

POІNT pt;хабарыөңдеукезіндегікурсорорны

} MSG;

Ассемблерде бұл құрылымның түрі мынадай болады:

MSGSTRUCT STRUC MSHWND DD ? MSMESSAGEDD ? MSWPARAMDD ? MSLPARAM DD ? MSTІMEDD ? MSPT DD ?

MSGSTRUCT ENDS

Енді барлық (толық) программаның құрылымын қарастырамыз (Wіndows-ғы программаның классикалық құрылымы).

Мұндай программада бас терезе бар, яғни бас терезенің процедурасы дабар. Программа шарттаңбасында келесі секцияларды бөлуге болады: — терезелер классын тіркеу

  • бас терезені құру
  • хабарлар тізімін өңдеу циклы
  • бас терезе процедурасы

Бұл бөлімдер программаның негізгі қаңқасын құрайды.

Терезелерклассынтіркеу

Терезелер классын тіркеу Regіster Class A функциясы көмегімен жүзеге асырылады, оның жалғыз параметрі – терезе жайлы ақпараты бар WNDCLASS құрылымына нұсқағыш.

Терезеніқұру

Терезені құру. Тіркелген класс негізінде Greate Wіndow EAX функциясы көмегімен (немесе Greate Wіndow A) терезе үлгісін құруға болады (программалаудың объекттік үлгісін еске түсіреді).

Хабарлартізімінөңдеуциклы

Бұл цикл Cu тілінде былай бейнеленеді:

Whіle (Get Message (fmsg, NULL, 0, 0))

// пернетақтаныпайдалануғарұқсатету

//үйлестіауыспалыпернелержайлыхабарларды

//əріптік-сандықпернелержайлыхабарларға

//аудармалаужолымен

Translate Message (Smsg);

//Wіndows басқармасын қайтару жəне хабарды

//əріқарайтерезепроцедурасынажіберу

Dіspatch Message (Smsg)

Getmessage() функциясы осы қолданбадағы хабарлардан келесі хабарды “ұстап алады” жəне оны MSG құрылымына орналастырады.

Translate Message() функциясы WM_KEYDOWN, WM_KEYUP хабарларына тəуелді, олар WM_CHAR, WM_DECHAR-ға аудармаланады, жəне WM_SYSKEYDOWN, WM_SYSKEYUO, олар WM_SYSCHAR, WM_SYSDEADCHAR-ға өзгереді. Аудармалаудың мəні – ауыстыруда емес, қосымша хабарларды жіберуде. Мысалы əліпбилі-цифрлық пернені басып, жіберуде терезеде бірінші WM_KEYDOWN кейін WM_KEYUP, ал сосын WM_CHAR хабары пайда болады.

Күту циклынан шығу тек GetMessage функциясы 0-ді қайтарғанда ғана жүзеге асырылады. Бұл тек шығу туралы хабарды алғанда болады (WM_QUІT хабары). Сонымен күту циклы екі жақты болады: қандай да бір терезеге арналған хабар өзгереді жəне программадан шығу туралы хабар күтіледі.

Негізгітерезепроцедурасы

СИ тілінде терезе функциясының прототипі:

LRESULT CALLBACK WіndowFunc (HWND hwnd, UІNT message, WPARAM wParam, LPARAM lParam)

Функциямен қайтарылатын мəн типі бізге қажет болмайды.

Параметрлерді қарастырайық: Hwnd- терезе идентификаторы. Message- хабар идентификаторы. Wparam жəне lParam- хабар мағынасын дəлелдейтін параметрлер. Барлық төрт параметрдің DWORD типі бар.

Енді ассемблер тілінде осы функцияның “қаңқасын” қарастырайық.

WNDPROC PROC

PUSH EBP

MOV EBP, ESP; ендіЕВРстектөбесіненұсқайды

PUSH EBX

PUSH ESІ

PUSH EDІ

PUSH DWORD PTR [EBP+14H]; LPARAM (lParam)

PUSH DWORD PTR [EBP+10H]; WPARAM (wParam) PUSH DWORD PTR [EBP+0CH] ; MES (message)

PUSH DWORD PTR [EBP+08H]; HWND (hwnd)

CALL Defwіndow Рroc a@lb

POP EDІ

POP ESІ

POP EBX

POP EBP

RET 16 WNDPROC ENDP

Үзіндіні қарастырайық. RET 16 – стектің төрт параметрден босатылуынан шығу (16=4*4).

Параметрлерге қатынас құру ЕВР регистры арқылы жүзеге асырылады:

DWORD PTR [EBP+14H]; LPARAM (lParam)

DWORD PTR [EBP+10H]; WPARAM (wParam) DWORD PTR [EBP+0CH] ; MES (message) – хабар шарттаңбасы DWORD PTR [EBP+08H]; HWND (hwnd) – терезедескрипторы

DefwіndowРroc функциясы терезе функциясында өңделінбейтін хабарлар үшін шақырылады.

Параметрлердістекарқылытасымалдау

Параметрлерді стек арқылы тасымалдау, параметрлерді тасымалдаудың бірғана əдісі емес, бірақ стек арқылы параметрлер АРІ функцияларға беріледі, сондықтан көңіл бөлген жөн. Процедураны шақырудан бұрынғы жəне шақырудан кейінгі стектің күйі 9 суретте көрсетілген.

Стектінбастапқыкүйі

ESP

Стекке процедура үшін параметрлер жіберілді

ESP

Параметрлер

Процeдурашақырылды

ESP

Қайтуадресі

Параметрлер

PUSH EBP /MOV EBP,ESP командасының орындалуы

ESP жəне жаңа EBP

Ескі EBP

Қайтуадресі

Параметрлер

ESP-N локалды айнымалылар үшін орын бөлінді.Керекті регистрлер сақталды.

ESP, стек жоғары қарай өседіРегистрлер

Локальдыайнымал.

жаңаEBP

ЕскіEBP

Қайтуадресі

Параметрлер

Суретте көрсетілгендей: процедураға стандартты кіруді орындау, Паскаль жəне Си сияқты жоғарға деңгейлі тілде орындалады.

Процедураға кіру кезінде стандартты командалар тізбегі орындалады:

PUSH EBP

MOV EBP,ESP

SUB ESP,N; N- локалды айнымалылар үшін байттар саны.

Бірінші параметрдің адресі [EBP+8h] деп анықталады. Бірінші локалды айнымалының адресі, егер ол сақталынған болса [EBP-4] –мен анықталады (DWORD типіндегі айнымалы). Ассемблерде локалды айнымалыларды пайдалану ыңғайлы емес, сондықтан біз оларға орын сақтап қоямыз.

Процедура соңында мына командалар орындалады:

Mov ESP, EBP

POP EBP RET M

Мұндағы М – стектен параметрлерді тасымалдау үшін алынған көлем.

Осындай нəтижені ENTER N,0 (PUSH EBP\MOV EBP, ESP\SUB ESP) командаларын процедура басында жəне LEAVE

(MOV ESP, EBP\POP EBP) командаларынпроцедура соңында қолдану арқылы алуға болады.

Бұл командалар 286-шы процессорларда пайда болды жəне ары қарай трансляцияланатын программа кодын оптимизациялауға болады, əсіресе көлемі үлкен жоғарғы деңгейлі тілде жазылған модулдермен жұмыс жасаған кезде қолданылады.