Assembly console alkalmazás írása
standard be és kimenet használata, I/O
Sziasztok!
Az alábbiakban egy egyszerű konzolos (console) alkalmazás általános felépítését fogjuk implementálni.
Egy tipikus konzolos programnak rendelkeznie kell adatbakérés és adatkiírás funkciókkal, ahol jellemzően a beolvasás billentyűzetről vagy egy fájlból történik, míg a kiírás a képernyőre vagy fájlba szövegként történik.
A mai bejegyzésben a billentyűzetről (stdin = standard bemenet) olvasunk be 2 karaktert, és a konzolra írjuk ki (stdout = standard kimenet)
Egy egyszerű konzolos program:
A program forráskódja:
Ahogy az elején látszik, összesen 4 külső (winapi) hívásra lesz szükségünk:
_GetStdHandle@4: ezzel a függvénnyel kapjuk meg az stdin és stdout mutatókat
_WriteFile@20: ezzel a függvénnyel fogunk írni a standard kimenetre
_ReadFile@20: ezzel a függvénnyel fogunk olvasni a standard bemenetről
_ExitProcess@4: ezzel a függvénnyel zárjuk be a programunkat
Belső függvényből pedig összesen 5 darabot írunk:
length: a függvény a paraméterként átadott memóriacímtől kezdve megszámolja, hogy az első 0-értékű byte-ig hány karakter áll. Magyarra lefordítva ez azt jelenti, hogy megnézi milyen hosszú a paraméterként átadott memóriahelyen kezdődő szöveg.
write: a függvény egy paramétert vár a veremből (stack), amiben egy szöveg (string) memóriacímének kell lennie, aminek a length függvény segítségével megnézi a hosszát majd a _WriteFile@20 winapi hívással kiírattatja a paraméterként átadott stringet. A függvénynek szüksége van egy 32 bites lokális változóra (locale variable) a winapi hívás egyik paraméteréhez, de ez implementálva van a függvényen belül.
read: ez a függvény 2 paramétert vár a veremből, amelyből az első paraméter egy olyan memóriacím amitől kezdődően a beolvasott bájtokat (byte) azaz karaktereket tárolni akarjuk, a második pedig, hogy összesen hány bájtot akarunk beolvasni a bemenetről. A függvénynek szüksége van egy 32 bites lokális változóra (locale variable) a winapi hívás egyik paraméteréhez, de ez implementálva van a függvényen belül.
exit: nem igényel paramétereket, egy winapi hívással bezárja a programot
_main: ez a programunk belépési pontja, innen kezdődik a program futása. Lekéri a standard bemenet és kimenet mutatóit majd elmenti őket az in és out "változókba" a write és a read függvény számára. Ezek után a message memóriacímtől kezdődően bekér 2 karaktert a read függvény segítségével, majd kiírattatja a message memóriacímen kezdődő szöveget a write függvény segítségével. Végül az exit hívással bezárja a programot.
Ezzel tehát elkészítettünk egy a standard be és kimenetet használó programot, ami bár nem csinál túl sok mindent, a további projektjeinkben mint kiindulási alapot használhatjuk. A program szerintem több magyarázatra nem szorul, ezzel a kis leírással adtam egy áttekintő képet, a működésnek a részleteiért a forráskódot elláttam elég részletes magyarázattal. A következő bejegyzésben leírom a legfontosabb assembly parancsokat, és működésüket, az az utániban pedig a verem működését illetve, hogy mire használjuk általában.
A forráskód lefordítása a szokott módon történik a compile.bat fájl megnyitása után:
nasm -fwin32 file.asm
gcc file.obj -o filename.exe
Ha valakinek még nincsen a gépén a nasm program, vagy a gcc, vagy esetleg nem készítette el a compile.bat fájlját akkor itt megteheti.