Tutorial 1: Základy

Tento tutorial předpokládá, že čtenář ví jako používat MASM. Pokud nejste obeznámeni s MASM, stáhněte si balíček win32asm.exe a prostudujte si texty uvnitř balíčku předtím, než se vrhnete na tento tutorial.
Dobře. Nyní jste připraveni. Pojďme na to! :)

Teorie:

Win32 programy běží v protected módu, který je podporován od 80286. Ale 80286 je již nyní dávná historie a my se můžeme v klidu soustředit na 80386 a jeho nástupce. Windows spouští každý Win32 program v odděleném virtuálním prostoru. To znamená, že každý Win32 program bude mít svůj vlastní 4 GB adresovací prostor. To všek neznamená, že každý win32 program má 4GB fyzické paměti, ale jen to, že každý program může adresovat adresu v tomto rozsahu. Windows učiní vše potřebné proto, aby jednotlivé odkazy do paměti byly funkční. Program samozřejmě musí přistoupit na pravidla daná Windows, jinak způsobí onu oblíbenou chybu ochrany. Každý program je sám o sobě ve vlastním adresovém prostoru. To je podstatná změna od dob Win16. Všechny Win16 aplikace se mohly navzájem vidět. Né tak pod Win32. Tenhle rys pomáhá redukovat šanci, že jeden program přepíše druhému kód nebo data.
Paměťový model je také drasticky odlišný od starého 16-bit světa. Pod Win32 se již vůbec nemusíme zabývat paměťovým modelem nebo segmenty. Existuje pouze jediný model: Flat memory model. Již žádné 64K segmenty. Paměť je veliký kontinuální prostor o velikosti 4GB. To také znamená, že si již nemusíte hrát se segment registry. Můžete využít libovolný segment registr k adresování jakéhokoliv místa v paměťovém prostoru. To je VELIKÁ pomoc programátorům a je to právě toto, co dělá Win32 programování v assembleru tak snadné jako C.
Když programujete pod Win32, musíte znát některá pravidla. Jedno takové pravidlo je, že Windows používá esi, edi, ebp a ebx registry vnitřně a nečeká, že se hodnoty v těchto registrech změní. Takže si zapamatujte pravidlo první: Jestliže použijete jakýkoliv z těchto registrů ve své callback funkci, nezapomeňte ho obnovit předtím, než vrátíte kontrolu Windows. Callback funkce je vaše vlastní funkce, která je volána operačním systémem. Běžným příkladem je Windows procedura. To ale neznamená, že nemůžete používat bezpečně tyto čtyři registry, jen je skutečně musíte obnovit před předáním kontroly zpět systému.

Content:

Zde je základní kostra programu. Jestliže nerozumíte něčemu z kodu, neděste se. Vysvětlím později.

.386
.MODEL Flat, STDCALL
.DATA
    <vaše inicializovaná data>
    ......
.DATA?
   <vaše neinicializovaná data>
   ......
.CONST
   <vaše konstanty>
   ......
.CODE
   <label>
    <váš kód>
   .....
    end <label>


Toť vše! Pojďme kostru zanalyzovat :).

.386
Toto je direktiva assembleru říkající, že budeme užívat 80386 instrukční sadu. Můžete také použít .486, .586, ale nejbezpečnější je zůstat u .386. Ve skutečnosti existují dvě téměř identické formy pro každý model CPU. .386/.386p, .486/.486p. Tyto verze "p" jsou nutné pouze když váš program používá privilegované instrukce, což jsou instrukce rezervované CPU/operačním systémem v protected módu, které může užívat pouze privilegovaný kód jako jsou ovladače. Většinu času váš program takto pracovat nebude, takže je bezpečné použít non-p verze.

.MODEL FLAT, STDCALL
.MODEL je direktiva, která specifikuje paměťový model vašeho programu. Pod Win32 je pouze jediný: FLAT model.
STDCALL říká MASM o způsobu předání parametrů (konvenci). Konvence určuje pořadí předávaných parametrů, zleva do prava nebo zprava doleva, a také určuje kdo bude balancovat zásobník po zavolání funkce.
Pod Win16 jsou dva druhy konvence, C a PASCAL
C konvence předává parametry zprava doleva, tj. parametr nejvíce vpravo je do zásobníku vložen jako první. Volající je zodpovědný za vybalancování zásobníku po zavolání. Např. pro zavolání funkce pojmenované foo(int prvni_param, int druhy_param, int treti_param) v C konvenci bude asm kód vypadat takto:

push  [treti_param]               ; Vloz (Push) treti parameter
push  [druhy_param]            ; nasleduje druhy
push  [prvni_param]                ; a nakonec prvni parametr
call    foo
add    sp, 12                                ; Volající balancuje zásobník
PASCAL konvence je obrácením C konvence. Předává parametry zleva doprava a volaný je zodpovědný za balancování zásobníku.
Win16 přijalo
PASCAL konvenci, protože produkuje menší kód. C konvence je užitečná, když nevíte kolik parametrů bude předáno funkci, jako v případě funkce wsprintf(). V případě wsprintf() funkce nemá možnost předem určit počet parametrů, takže nemůže balancovat zásobník.
STDCALL je křížencem mezi C a PASCAL konvencí. Předává paramety zprava doleva, ale za balancování zásobníku je zodpovědný volaný. Win32 platforma používá výlučně STDCALL konvenci. Kromě jediné vyjímky: wsprintf(). Tam musíte užít C konvenci.

.DATA
.DATA?
.CONST
.CODE

Všechny čtyři direktivy jsou tím co se nazývá sekce. Řekli jsme si, že ve Win32 nemáme segmenty. Ale můžeme rozdělit přidělený adresový prostor do čtyř logických úseků (sekcí). Začátek jedné ze sekcí označuje zároveň konec sekce předchozí. Existují dvě skupiny: data sekce a code sekce. Data sekce jsou rozdělena do 3 kategorií:

Nemusíte však využít všechny tři sekce. Deklarujte pouze ty, které budete potřebovat.

Pro samotný kód je pouze jedna sekce:.CODE. Zde přebývá váš kód.

<label>
end <label>
kde <label> je libovolný label, který určuje prostor, kde je umístěn kód. Oba labely musejí být identičtí.  Veškerý kód musí být mezi <label> a end <label>


[Iczelion's Win32 Assembly HomePage]
Překlad Shaldan 2006, fx.s@seznam.cz - při četbě a využívání nových poznatků z četby opravdu za nic neručím :))