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