Programowanie w języku asembler w systemie Windows
Dominik Szałkowski
Zakład Informatyki UMCS
dominik.szalkowski@umcs.lublin.pl
http://hektor.umcs.lublin.pl/˜dominisz
17 lutego 2006
1
D. Szałkowski, Programowanie w języku asembler w systemie Windows
2
Spis treści
1
Wstęp
3
2
Asembler
3
2.1
Kompilacja w wierszu poleceń . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3
2.2
Kompilacja przy pomocy QuickEditora . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3
2.3
Opcje asemblera
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3
2.4
Opcje linkera . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4
3
Program uruchomieniowy
5
3.1
Wygląd programu
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5
3.2
Obsługa programu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5
4
Szablon programu
5
5
Funkcje systemowe Windows
6
5.1
Standardowe wywołanie funkcji . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6
5.2
Wywołanie za pomocą dyrektywy invoke . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6
5.3
Przykład . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6
5.4
Operacje na plikach
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
7
6
Literatura
8
7
Zrzuty ekranu
9
D. Szałkowski, Programowanie w języku asembler w systemie Windows
3
1
Wstęp
Najnowszą wersję tego dokumentu, przykładowe programy oraz inne pomoce można znaleźć na stronie
http://hektor.umcs.lublin.pl/~dominisz/
Na adres dominik.szalkowski@umcs.lublin.pl proszę przysyłać uwagi na temat tego dokumentu (zna-
lezione błędy, nieścisłości, braki).
2
Asembler
Na stronie http://www.masm32.com dostępna jest pełna, darmowa wersja Microsoft Asemblera.
2.1
Kompilacja w wierszu poleceń
Utworzenie programu wykonywalnego z pliku asemblerowego przebiega dwuetapowo. Pierwszym krokiem
jest kompilacja a drugim łączenie (linkowanie) z bibliotekami (rys. 1).
c:\masm32\bin\ml /c /coff /Cp /Zi nazwa_pliku.asm
c:\masm32\bin\link /SUBSYSTEM:WINDOWS nazwa_pliku.obj
2.2
Kompilacja przy pomocy QuickEditora
Edytor tekstu QuickEditor jest wstępnie skonfigurowany tak, że wykorzystuje Microsoft Asembler. Kom-
pilacja i łączenie wykonywana jest po wybraniu odpowiedniej opcji z menu (Project → Assemble&Link)
(patrz rys. 2, 3, 4). Z poziomu Quick Editora możemy także uruchomić program wybierając Project →
Run program (rys. 5).
2.3
Opcje asemblera
Microsoft (R) Macro Assembler Version 6.14.8444
Copyright (C) Microsoft Corp 1981-1997.
All rights reserved.
ML [ /options ] filelist [ /link linkoptions ]
/AT Enable tiny model (.COM file)
/nologo Suppress copyright message
/Bl<linker> Use alternate linker
/Sa Maximize source listing
/c Assemble without linking
/Sc Generate timings in listing
/Cp Preserve case of user identifiers
/Sf Generate first pass listing
/Cu Map all identifiers to upper case
/Sl<width> Set line width
/Cx Preserve case in publics, externs
/Sn Suppress symbol-table listing
/coff generate COFF format object file
/Sp<length> Set page length
/D<name>[=text] Define text macro
/Ss<string> Set subtitle
/EP Output preprocessed listing to stdout /St<string> Set title
/F <hex> Set stack size (bytes)
/Sx List false conditionals
/Fe<file> Name executable
/Ta<file> Assemble non-.ASM file
/Fl[file] Generate listing
/w Same as /W0 /WX
/Fm[file] Generate map
/WX Treat warnings as errors
/Fo<file> Name object file
/W<number> Set warning level
/FPi Generate 80x87 emulator encoding
/X Ignore INCLUDE environment path
/Fr[file] Generate limited browser info
/Zd Add line number debug info
/FR[file] Generate full browser info
/Zf Make all symbols public
/G<c|d|z> Use Pascal, C, or Stdcall calls /Zi Add symbolic debug info
/H<number> Set max external name length
/Zm Enable MASM 5.10 compatibility
D. Szałkowski, Programowanie w języku asembler w systemie Windows
4
/I<name> Add include path
/Zp[n] Set structure alignment
/link <linker options and libraries>
/Zs Perform syntax check only
2.4
Opcje linkera
Microsoft (R) Incremental Linker Version 5.12.8078
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.
usage: LINK [options] [files] [@commandfile]
options:
/ALIGN:#
/BASE:{address|@filename,key}
/COMMENT:comment
/DEBUG
/DEBUGTYPE:{CV|COFF}
/DEF:filename
/DEFAULTLIB:library
/DLL
/DRIVER[:{UPONLY|WDM}]
/ENTRY:symbol
/EXETYPE:DYNAMIC
/EXPORT:symbol
/FIXED[:NO]
/FORCE[:{MULTIPLE|UNRESOLVED}]
/GPSIZE:#
/HEAP:reserve[,commit]
/IMPLIB:filename
/INCLUDE:symbol
/INCREMENTAL:{YES|NO}
/LARGEADDRESSAWARE[:NO]
/LIBPATH:dir
/MACHINE:{ALPHA|ARM|IX86|MIPS|MIPS16|MIPSR41XX|PPC|SH3|SH4}
/MAP[:filename]
/MAPINFO:{EXPORTS|FIXUPS|LINES}
/MERGE:from=to
/NODEFAULTLIB[:library]
/NOENTRY
/NOLOGO
/OPT:{ICF[,iterations]|NOICF|NOREF|NOWIN98|REF|WIN98}
/ORDER:@filename
/OUT:filename
/PDB:{filename|NONE}
/PDBTYPE:{CON[SOLIDATE]|SEPT[YPES]}
/PROFILE
/RELEASE
/SECTION:name,[E][R][W][S][D][K][L][P][X]
/STACK:reserve[,commit]
/STUB:filename
/SUBSYSTEM:{NATIVE|WINDOWS|CONSOLE|WINDOWSCE|POSIX}[,#[.##]]
/SWAPRUN:{CD|NET}
/VERBOSE[:LIB]
D. Szałkowski, Programowanie w języku asembler w systemie Windows
5
/VERSION:#[.#]
/VXD
/WARN[:warninglevel]
/WINDOWSCE:{CONVERT|EMULATION}
/WS:AGGRESSIVE
3
Program uruchomieniowy
Na stronie http://www.ollydbg.de dostępny jest program uruchomieniowy (inaczej debugger) Ollydbg.
Program ten umożliwia krokowe uruchamianie programów, oglądanie instrukcji znajdujących się w seg-
mencie kodu, oglądanie zmiennych znajdujących się w segmencie danych.
3.1
Wygląd programu
Okno programu podzielone jest na cztery części (rys. 6). W lewej górnej części przedstawione są instruk-
cje znajdujące się w segmencie kodu. Poniżej widać zmienne zdefiniowane w segmencie danych (można
zmienić sposób wyświetlania segmentu danych (rys. 7)). W prawym górnym rogu znajduje się okienko
przedstawiające stan procesora (wartości rejestrów i znaczników, na czerwono zaznaczone są rejestry, któ-
re zmieniły swoją wartość po wykonaniu ostatniej instrukcji). Poniżej znajduje się okno przedstawiające
stos.
3.2
Obsługa programu
Po wczytaniu programu (File → Open) możemy go uruchomić wybierając z menu Debug opcję Run
(rys. 8). Spowoduje to wykonanie całego programu i powrót do programu uruchomieniowego. Jeżeli
chcemy wykonywać kolejno pojedyńcze instrukcje programu musimy wybrać opcję Debug → Step Into
lub Debug → Step Over (od poprzedniej opcji różni się tym, że podczas wykonywania nie przechodzimy
do procedur). Przed ponownym uruchomieniem program musimy zrestartować wybierając Debug →
Restart.
Uwaga: jeżeli w debuggerze wczytany mamy program to nie powiedzie się jego ponowna kompilacja.
Najpierw należy program zamknąć wybierając Debug → Close lub zamykając program uruchomieniowy.
4
Szablon programu
Poniżej znajduje się szablon programu asemblerowego. Zmienne definiujemy w segmencie danych (po
dyrektywie .data, instrukcje wpisujemy w segmencie kodu (dyrektywa .code) po etykiecie start.
;tryb 32-bitowy
.386
;płaski model pamięci, konwencja wywoływania procedur
.model flat, stdcall
;zwracamy uwagę na wielkość liter
option casemap:none
;stałe i typy do programowania w systemie windows, zawsze na początku
include C:\masm32\include\windows.inc
;różne funkcje interfejsu użytkownika
include C:\masm32\include\user32.inc
;funkcje jądra systemu operacyjnego
include C:\masm32\include\kernel32.inc
;funkcje związane z grafiką
include C:\masm32\include\gdi32.inc
D. Szałkowski, Programowanie w języku asembler w systemie Windows
6
;dołączamy biblioteki
includelib C:\masm32\lib\user32.lib
includelib C:\masm32\lib\kernel32.lib
includelib C:\masm32\lib\gdi32.lib
; Początek segmentu danych
.data
; Koniec segmentu danych
; Poczatek segmentu kodu
.code
;od tej etykiety rozpocznie się wykonywanie programu
start:
;powrót do systemu operacyjnego za pomocą funkcji systemowej
invoke ExitProcess,0
;dyrektywa end mówi asemblerowi, od której etykiety zacząć
end start
; Koniec segmentu kodu
5
Funkcje systemowe Windows
Opis funkcji systemowych Windows można znaleźć w ”Win32 Programmer’s Reference” (jest to najczę-
ściej plik o nazwie win32.hlp).
5.1
Standardowe wywołanie funkcji
Standardowe wywołanie funkcji polega na odłożeniu parametrów funkcji na stosie (w odwrotnej kolejno-
ści) i wywołaniu jej za pomocą instrukcji call. Wartość funkcji jest zwracana w rejestrze eax.
5.2
Wywołanie za pomocą dyrektywy invoke
Innym sposobem wywołania funkcji systemowej jest wykorzystanie dyrektywy invoke. Parametry po-
dajemy w normalnej kolejności, wartość funkcji zwracana jest w rejestrze eax. Dodatkowo sprawdzana
jest poprawność parametrów. Aby wykorzystać tę dyrektywę do programu musimy dodać pliki z opisami
funkcji systemowych, deklaracjami stałych, itp.
include c:\masm32\include\windows.inc
include c:\masm32\include\kernel32.inc
include c:\masm32\include\user32.inc
5.3
Przykład
Wykorzystamy funkcję MessageBox do wyświetlenia okienka z komunikatem. Nagłówek tej funkcji (zgod-
nie z ”Win32 Programmer’s Reference”) jest następujący:
int MessageBox(
HWND hWnd,// handle of owner window
LPCTSTR lpText,// address of text in message box
LPCTSTR lpCaption,// address of title of message box
UINT uType
// style of message box
);
D. Szałkowski, Programowanie w języku asembler w systemie Windows
7
Parametry lpText i lpCaption czyli tekst do wyświetlenia oraz tytuł okna to adresy łańcuchów za-
kończonych zerem (tzw. null-terminated string). Parametr UINT uType określa wygląd okna i może
przyjmować jedną z następujących wartości lub ich kombinację: MB OK, MB OKCANCEL, MB YES, MB YESNO,
MB ICONEXCLAMATION, MB ICONSTOP, MB ICONWARNING (istnieją także inne stałe). Kod źródłowy programu
będzie wyglądał następująco:
; -----------------------------
; początek pliku messagebox.asm
; -----------------------------
.386
.model flat,stdcall
option casemap:none
include c:\masm32\include\windows.inc
include c:\masm32\include\kernel32.inc
includelib c:\masm32\lib\kernel32.lib
include c:\masm32\include\user32.inc
includelib c:\masm32\lib\user32.lib
.data
TytulOkna db "Okienko MessageBox",0
TrescKomunikatu db "Komunikat w okienku MessageBox",0
.code
start:
; wywołujemy za pomocą invoke
invoke MessageBox, NULL, offset TrescKomunikatu, offset TytulOkna, MB_OK
; wywołujemy standardowo
push MB_OK
push offset TytulOkna
push offset TrescKomunikatu
push NULL
call MessageBox
invoke ExitProcess, NULL
; lub alternatywnie
; push 0
; call ExitProcess
end start
; ---------------------------
; koniec pliku messagebox.asm
; ---------------------------
5.4
Operacje na plikach
Do wykonywania operacji na plikach służą funkcje systemowe CreateFile (otwieranie istniejącego pliku
i tworzenie nowego pliku), CloseHandle (zamykanie otwartego pliku), ReadFile (odczytanie danych z
pliku), WriteFile (zapisanie danych do pliku).
D. Szałkowski, Programowanie w języku asembler w systemie Windows
8
invoke CreateFile, ; identyfikator funkcji systemowej
offset nazwa_pliku, ; adres nazwy pliku, zakończona 0
GENERIC_READ, ; otwieramy do odczytu
0, NULL,
OPEN_EXISTING, ; otwieramy istniejący plik
FILE_ATTRIBUTE_NORMAL,
NULL
mov uchwyt_pliku, eax ; kopiujemy uchwyt pliku
invoke CreateFile, ; identyfikator funkcji systemowej
offset nazwa_pliku, ; adres nazwy pliku, zakończona 0
GENERIC_WRITE, ; otwieramy do zapisu
0, NULL,
CREATE_NEW, ; tworzymy nowy plik
FILE_ATTRIBUTE_NORMAL,
NULL
mov uchwyt_pliku, eax ; kopiujemy uchwyt pliku
invoke CloseHandle, ; identyfikator funkcji systemowej
uchwyt_pliku ; uchwyt pliku do zamknięcia
invoke ReadFile, ; identyfikator funkcji systemowej
uchwyt_pliku, ; uchwyt pliku, z którego czytamy
offset bufor, ; adres, pod który odczytujemy
ile_odczytac, ; liczba bajtów do odczytania
offset ile_odczytano, ; liczba faktycznie odczytanych bajtów
NULL
invoke WriteFile, ; identyfikator funkcji systemowej
uchwyt_pliku, ; uchwyt pliku, do którego zapisujemy
offset bufor, ; adres, spod którego zapisujemy
ile_zapisac, ; liczba bajtów do zapisania
offset ile_zapisano, ; liczba faktycznie zapisanych bajtów
NULL
6
Literatura
• M. Kotowski ”Pod zegarem”, Wydawnictwo Lupus, Warszawa 1993
• G. Michałek ”Co i jak w assemblerze czyli poradnik dla średnio zaawansowanych”, Intersoftland,
Warszawa 1992
• G. Michałek ”Co i jak w assemblerze, część druga”, Intersoftland, Warszawa 1992
• L. Bułhak, R. Goczyński, M. Tuszyński ”DOS od środka”, Komputerowa Oficyna Wydawnicza
”Help”, Warszawa 1990
• H. Małysiak, B. Pochopień, E. Wróbel ”Procesory arytmetyczne”, WNT, Warszawa 1993
• L. J. Scanlon ”Assembler 8086/8088/80286”, Intersoftland, Warszawa 1992
• S. M. Money ”Mikroprocesory”, WKŁ, Warszawa 1996
• R. Goczyński, M. Tuszyński ”Mikroprocesory 80286, 80386 i i486”, Komputerowa Oficyna Wydaw-
nicza ”Help”, Warszawa 1991
D. Szałkowski, Programowanie w języku asembler w systemie Windows
9
Rysunek 1: Kompilacja w wierszu poleceń
• S. Kruk ”Asembler w Windows”, Komputerowa Oficyna Wydawnicza ”Help”, Michałowice 2005
7
Zrzuty ekranu
D. Szałkowski, Programowanie w języku asembler w systemie Windows
10
Rysunek 2: Kompilacja w QuickEditorze
Rysunek 3: Kompilacja przebiegła pomyślnie
D. Szałkowski, Programowanie w języku asembler w systemie Windows
11
Rysunek 4: Błędy podczas kompilacji
Rysunek 5: Uruchomienie programu
D. Szałkowski, Programowanie w języku asembler w systemie Windows
12
Rysunek 6: Program uruchomieniowy
Rysunek 7: Zmiana sposobu wyświetlania segmentu danych
D. Szałkowski, Programowanie w języku asembler w systemie Windows
13
Rysunek 8: Krokowe uruchamianie programu