IPA - Lab.1 Úvod do programování v ASM Ondřej Klubal http://www.fit.vutbr.cz/~iklubal/ipa/ 2014 Ondřej Klubal IPA - Lab.1 1 / 16
Osnova Nástroje Konvence volání Použití DLL Windows API Makra NASM + VS 2010 Cvičení Ondřej Klubal IPA - Lab.1 2 / 16
Co budeme potřebovat/používat Čistý assembler (NASM): Compiler - Netwide ASseMbler (NASM) http://www.nasm.us/ Dokumentace http://www.nasm.us/doc/ Linker - alink http://alink.sourceforge.net/ Debugger - OllyDebugger http://www.ollydbg.de/ Smíšený kód (C/C++, MASM): MS Visual Studio 2010 inline assembler (option /FA), intrinsic functions (MMX, SSE) (option /Oi) Smíšený kód (C/C++, NASM): MS Visual Studio 2010 + NASM Ondřej Klubal IPA - Lab.1 3 / 16
(Úloha B) MS Visual Studio 2010 + NASM 1 Ondřej Klubal IPA - Lab.1 4 / 16
(Úloha B) MS Visual Studio 2010 + NASM 2 Command Line: nasm.exe -f win32 -Xvc -o "$(IntDir)\$ (InputName).obj" "$(InputDir)\$(InputName).asm" Outputs: "$(IntDir)\$(InputName).obj" Ondřej Klubal IPA - Lab.1 5 / 16
Datové typy Ondřej Klubal IPA - Lab.1 6 / 16
Volací koncence Ondřej Klubal IPA - Lab.1 7 / 16
Volací koncence cdecl, stdcall, pascal, fastcall lze specifikovat přímo při deklaraci funkce v C/C++ (nutná podpora překladače) cdecl je výchozí konvencí v rámci aplikace a statických knihoven stdcall je výchozí konvencí pro systmová volání a dynamické knihovny (32-bit Windows) Ondřej Klubal IPA - Lab.1 8 / 16
Předávání parametrů Zprava do leva (konvence) void f(int arg1, int ar2,int arg3) Zásobník roste se snižující se adresou (vrchol zásobníku má nenižší adresu) Příklad (stackframe): Ondřej Klubal IPA - Lab.1 9 / 16
Použití funkcí z dynamických knihoven Funkce jsou z externího zdroje (DLL) Direktivy extern a import: extern fce_z_dll import fce_z_dll knihovna.dll fce_z_dll_pro_fit Pozor - nepřímé volání dobře: call [fce_z_dll] špatně: call fce_z_dll Ondřej Klubal IPA - Lab.1 10 / 16
Windows API Win32 API je aplikační rozhraní 32bit Windows Potřebujeme pro komunikaci s uživatelem/zařízeními (I/O funkce) je třeba do zdojového textu vložit win32n.inc (direktiva %include) Řetězce ANSI a UNICODE: ANSI == 8 bit ASCII MessageBoxA UNICODE == 16 bit MessageBoxW Ondřej Klubal IPA - Lab.1 11 / 16
Windows API - funkce pro práci s konzolí - kernel32.dll Získání handle na standartní vstup/výstup HANDLE WINAPI GetStdHandle(DWORD nstdhandle); Čtení z konzole BOOL WINAPI ReadConsole( _In_ HANDLE hconsoleinput, _Out_ LPVOID lpbuffer, _In_ DWORD nnumberofcharstoread, _Out_ LPDWORD lpnumberofcharsread, _In_opt_ LPVOID pinputcontrol ); Čtení z konzole BOOL WINAPI WriteConsole( _In_ HANDLE hconsoleoutput, _In_ const VOID *lpbuffer, _In_ DWORD nnumberofcharstowrite, _In_ LPDWORD lpnumberofcharswritten, _Reserved_ LPVOID lpreserved ); Ukončení aplikace: VOID WINAPI ExitProcess(UINT uexitcode); Ondřej Klubal IPA - Lab.1 12 / 16
(Úloha A) NASM 1/2 ; 1) Definujeme potřebné symboly STD_OUT_HANDLE equ -11 NULL equ 0 ; je vhodné použít %include inc/win32n.inc, kde jsou tyto definovány ; 2) import externích funkcí použitých ve vaší aplikaci - doplňte extern GetStdHandle import GetStdHandle kernel32.dll ; je vhodné použít %include inc/general.mac, kde jsou tyto užitečná makra: ; dllimport (import funkcí z dll) ; invoke (voální funkcí) ; string (definice řetězců) ; Použití: ; dllimport ReadConsole, kernel32.dll, ReadConsoleA ; dllimport GetStdHandle, kernel32.dll ;definice datového segmentu - proměnné [section.data use32 class=data] smessage db "Zadejte cislo: ", 10, 0 ; string smessage, "Zadejte cislo: ",10 dwwritten dd 0... Ondřej Klubal IPA - Lab.1 13 / 16
(Úloha A) NASM 2/2... ;definice kódového segmentu [section.code use32 class=code]..start: push dword STD_OUT_HANDLE call [GetStdHandle]... Překlad: nasm -fobj NazevSouboru.asm alink -ope -subsys con NazevSouboru.obj nebo run.bat NazevSouboru Ondřej Klubal IPA - Lab.1 14 / 16
Cvičení Úloha A) NASM - vytvořte aplikaci, která načte číslo ze standardního vstupu na standardní výstup vypíše, zda se jedná o liché nebo sudé číslo používejte makra z general.mac Úloha B) MS Visual Studio 2010 + NASM v add.asm doplňte těla funkcí _addcdecl a _addstdcall (funkce má sečíst dvě čísla předaná jako parametr a vrátit výsledek) v main.cpp je nutno povolit volání a import těchto funkcí, aby byl vypsán výsledek vytvořte funkci numtoascii, která převede číslo na řetězec (ASM část vložte do add.asm, volání a výpis proveďte v main.cpp) Ondřej Klubal IPA - Lab.1 15 / 16
Děkuji za Vaši pozornost (příště MMX a optimalizace) Ondřej Klubal IPA - Lab.1 16 / 16