Assembler - szkielet programu & kilka pojęć.

Status
Zamknięty.

0wn3r

Były Moderator
Dołączył
Marzec 10, 2007
Posty
1330
Przykładowy szkielet programu wygląda w ten sposób :

Kod:
.386.MODEL FLAT, STDCALL
OPTION CASEMAP:NONE


.DATA; twoje zainicjowane dane

.DATA?; twoje niezainicjowane dane

.CONST; stałe

.CODE; twój kod źródłowy programu
start :; etykieta

END start; koniec etykiety

Teraz zajmijmy się objaśnieniem paru spraw.

.386 - dyrektywa procesora, informująca assembler aby korzystać z instrukcji procesora o numerze 80386.

.MODEL FLAT, STDCALL.
.MODEL - dyrektywa assemblera określająca pamięć twojego programu. W Windows32 istnieje tylko 1 model pamięci, a zwie się on jak wcześniej wspominaliśmy FLAT.
STDCALL - konwencja przekazywania parametrów dla procedur oraz funkcji, umieszcza parametry na stosie od lewej do prawej lub od prawej do lewej.

.DATA - zawiera zainicjowane dane twojego programu.
.DATA? - zawiera niezainicjowane dane twojego programu.

.CONST - zawiera deklaracje stałych, używanych przez Twój program.

.CODE - zawiera twój kod programu
Etykieta - jest dowolną etykietą do określenia zasięgu twojego kodu.
END etykieta - koniec kodu źródłowego

Po wyjaśnieniu wszystkiego, czas teraz napisać jakiś program. Aby napisać jakiś program, przyda nam się MASM32, można go pobrać na www.protools.cjb.net
Po zainstalowaniu MASMA, pliki będziemy zapisywać do jego folderu, nigdzie indziej, bo przy kompilacji mogą wystąpić błędy.

Źródło zwykłego programu, wyświetlającego okienko z tytułem jaki sobie ustalimy tekstem i przyciskiem OK oraz jego analiza.

Kod:
.386; dyrektywa procesora informująca assembler aby korzystać z 80386
.MODEL FLAT, STDCALL; dyrektywa określająca pamięć twojego programu
OPTION CASEMAP:NONE; dodatek, duże i małe litery są brane pod uwagę


INCLUDE include\windows.inc; dołączamy windows.inc
INCLUDE include\kernel32.inc; dołączamy kernel32.inc
INCLUDELIB lib\kernel32.lib; dołączamy kernel32.lib
INCLUDE include\user32.inc; dołączamy user32.inc
INCLUDELIB lib\user32.lib; dołączamy user32.lib

.DATA; zainicjowane dane
MsgBoxCaption DB "Program w Assemblerze",0; tytuł okna
MsgBoxText DB "Moj pierwszy program w Assemblerze",0; tekst w oknie

.CODE; kod źródłowy programu
start:; etykieta
INVOKE MessageBox, NULL, ADDR MsgBoxText, ADDR MsgBoxCaption, MB_OK; wywołanie
; okienka
INVOKE ExitProcess, NULL; wyłączenie programu
END start; koniec etykiety

A teraz czas na analizę kodu wyżej przedstawionego.

Zobaczmy na :

Kod:
INCLUDE \masm32\include\windows.inc

Bo jest to dla nas nowość, nie omawiałem tego wcześniej. A mianowicie plik windows.inc zawiera definicje stałych i struktur niezbędnych do programowania w języku assembler.

INVOKE, moim zdaniem jest lepsze niż funkcja call, ponieważ assembler informuje Cię o popełnionym błędzie. Składnia Invoke jest następująca :

Kod:
INVOKE wyrażenie [,jakis_argument]

Czyli np. INVOKE ExitProcess, NULL

Prototyp funkcji MessageBox ma następującą postać :

Kod:
MessageBox PROTO hwnd:DWORD, lpText:DWORD, lpCaption:DWORD, uType:DWORD

hwnd - handle czyli uchwyt programu, możesz to traktować jako liczbę, która będzie Ci reprezentowała okno twojego programu.
lpText - jest to wskazanie tekstu, który ma być wyświetlany w twoim oknie
lpCaption - poprostu tytuł twojego okienka
uType - określa liczbę użytych w twoim programie przycisków

ADDR - obsługuje zmienne lokalne, jego przeciwieństwem jest może wam znany OFFSET. Zmienne lokalne są jedynie pewnym miejscem zarezerwowanym na stosie waszego procesora. Adres ten, będzie tylko znany w trakcie uruchomionego się programu. Natomiast operator OFFSET, przetwarzany jest podczas procesu assemblacji przez wybrany przez was assembler. Jak mówiłem jest to przeciwieństwo ADDR, czyli nie funkcjonuje on na zmiennych lokalnych.

Informacje na temat plików DLL.
Kernel32.dll zawiera funkcje API obsługujące zarządzanie pamięcią oraz procesami.

User32.dll zawiera funkcje obsługujące aspekty interfejsu użytkownika dla twojego programu.

Gdi32.dll jest odpowiedzialna za operacje graficzne.

Rejestry. Jeśli programujemy w Windows32 musimy znać kilka prostych zasad
<
System Windows wykorzystuje dla swoich potrzeb rejestry takie jak esi, edi, ebp, ebx. Jeśli używasz któregoś z tych rejestrów w funkcji zwrotnej np. callback to nie możesz go zapomnieć odtworzyć przed powrotem.

Konwencja typu C & Pascal :

Kod:
push [p3]; Umieść na stosie trzeci parametr
push [p2]; Umieść na stosie parametr 2
push [p1]; Oraz pierwszy
call foo
add sp, 12; Po wykonaniu, usuń parametry ze stosu

Innej kolejności nie ma.

Rejestry:
Accumulator
32 bitowe - eax
16 bitowe - ax
8 bitowe - ah, al
Używamy ich do operacji arytmetycznych & logicznych

Base
32 bitowe - ebx
16 bitowe - bx
8 bitowe - bh, bl
Używamy ich jako podstawę do wyznaczenia adresu

Counter
32 bitowe - ecx
16 bitowe - cx
8 bitowe - ch, cl
Używany do zliczania liczb przejść pętli (np. LOOP i REP)

Data
32 bitowe - edx
16 bitowe - dx
8 bitowe - dh, dl

Rejestry stosu:

Base Pointer -
32 bitowe - ebp
16 bitowe - bp
Wskaźnik używany przy adresowaniu pamięci.

Stack Pointer
32 bitowe - esp
16 bitowe - sp
Wskaźnik stosu.

Rejestry wskaźnikowe
Source Index
32 bitowe - esi
16 bitowe - si
Wskazuje miejsce w pamięci, skąd są przesyłane dane.

Destination Index
32 bitowe - edi
16 bitowe - di
Wskazuje miejsce w pamięci, dokąd są przesyłane dane.

Instruction Pointer
32 bitowe - eip
16 bitowe - ip
Wskazuje następną instrukcję w segmencie.

Zachęcam was do nauki assemblera, bo warto.
 
Status
Zamknięty.
Do góry Bottom