background image

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

background image

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

background image

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

background image

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]

background image

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

background image

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

);

background image

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).

background image

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

background image

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

background image

D. Szałkowski, Programowanie w języku asembler w systemie Windows

10

Rysunek 2: Kompilacja w QuickEditorze

Rysunek 3: Kompilacja przebiegła pomyślnie

background image

D. Szałkowski, Programowanie w języku asembler w systemie Windows

11

Rysunek 4: Błędy podczas kompilacji

Rysunek 5: Uruchomienie programu

background image

D. Szałkowski, Programowanie w języku asembler w systemie Windows

12

Rysunek 6: Program uruchomieniowy

Rysunek 7: Zmiana sposobu wyświetlania segmentu danych

background image

D. Szałkowski, Programowanie w języku asembler w systemie Windows

13

Rysunek 8: Krokowe uruchamianie programu