2017. jan 08.

Assembly console alkalmazás írása

írta: Ra0k
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:

Why is the console window closing immediately without displaying my output

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.




                        
Szólj hozzá

read exit x86 write length IO Programozás I/O GCC Console Assembly Nasm Programnyelv