Assembler – Windows API
MessageBox
Navrhovaný program má vytvoriť dialógové okno a skončiť. Dialógové okno vytvoríme volaním API funkcie MessageBox a o ukončenie programu sa postaráme funkciou rozhrania API nazývanou ExitProcess.
V dokumentácii k MessageBox sa dočítame:
int MessageBox ( IFWND hWnd, // handle of owner window LPCTSTR lpText, // address of text in message box LPCTSTR lpCaption, // address of title of message box UINT Utype // style of message box );
Prvým parametrom bude popisovač vlastného okna. Žiadny nemáme, preto predáme nulu. Druhým parametrom je ukazovateľ na text, ktorý sa v dialógovom okne zobrazí (klasický reťazec zakončený nulovým byte), tretím ukazovateľom je text titulku okna. Posledný parameter určuje typ dialógového okna (použijeme symbolickú konštantu MB_OK – z include súboru, viď ďalej).
Druhé volanie API funkcie ExitProcess, rovnako ako v DOSe, svojím jediným parametrom určuje chybový kód ukončeného programu. Po jeho zavolaní program skončí.
Aby bol život programátora v assembleri jednoduchší, bol vytvorený “include súbor” win32n.inc, v ktorom sú definované všetky typy parametrov API (napr. HWND aj LPCTSTR zodpovedajú v assembleri obyčajnému dvojslovu – dword) i hodnoty symbolických konštánt. Do programu tento súbor vložíme direktívou include:
%include "win32n.inc"; vložíme súbor win32n.inc
Použité API funkcie uložené v dynamických knižniciach nesmieme zabudnúť sprístupniť nášmu programu. Stačí použiť direktívy EXTERN a IMPORT:
EXTERN MessageBox ; symbol MessageBox je definovaný inde
IMPORT MessageBox user32.dll ; konkrétne v user32.dll
EXTERN ExitProcess ; symbol ExitProcess je definovaný inde
IMPORT ExitProcess kernel32.dll ; konkrétne v kernel32.dll
Zostáva vyriešil jediný problém: Ako odovzdať API funkciám jednotlivé parametre. Zoznámime sa tu len stručne s odovzdávacími konvenciiami parametrov rozhrania Win32 API.
Predávaciia konvencia sa volá STDCALL. Parametre sa odovzdávajú cez zásobník sprava doľava (ako v jazyku C), vymazanie zásobníka vykonáva volaný (ako v jazyku Pascal).
Na zásobník uložíme parametre inštrukciami PUSH, požadovanú funkciu zavoláme nepriamo inštrukciou CALL, o vymazanie zásobníka sa nemusíme starať. Celý program bude vyzerať nasledovne (pro prekladac NASM):
% include "win32n.inc" ; vložíme súbor win32n.inc EXTERN MessageBox ; symbol MessageBox je definovaný inde IMPORT MessageBox user32.dll ; konkrétne v user32.dll EXTERN ExitProcess ; symbol ExitProcess je definovaný inde IMPORT ExitProcess kernel32.dll ; konkrétne v kernel32.dll SECTION CODE USE32 CLASS = CODE ; začiatok kódovej sekcie .start: ; špeciálne návestie pre linker, ktoré označuje vstupný bod programu z (entrypointu) push UINT MB OK ; na zásobník uložíme posledný parameter, dialógové okno bude mať len tlačidlo OK push LPCTSTR titulok ; na zásobník vložíme adresu reťazca ukončeného nulovým byte, ktorý sa zobrazí ako titulok okna push LPCTSTR napis ; na zásobník vložíme adresu reťazca ukončeného nulovým byte, ktorý sa zobrazí ako text okna push HWND NULL ; na zásobník uložíme nulu, žiadne nadradené okno nemáme call [MessageBox] ; zavoláme API - vytvoríme dialógové okno návrat až po stlačení tlačidla OK push UINT NULL ;vrátime rodičovi nulový chybový kód call [ExitProcess] ;ukončíme proces SECTION DATA USE32 CLASS=DATA napis db 'Hello world',OxD,OxA,0 ;reťazec Hello, World! vrátane odriadkovania titulek db 'Hello", 0 ;titulok okna bude hello