Uruchom wcześniej przygotowany
projekt. Kod programu opisywanego w tej części to:
.386
.model flat, stdcall
.stack 4096
include kernel32.inc
includelib kernel32.lib
.data
dwSuma DWORD 0
.code
main PROC
mov eax, 5
add eax, 11
mov dwSuma, eax
invoke ExitProcess, eax
main ENDP
END main
|
Zmienna jest to element programu
służący do przechowywania danych. Korzystając z asemblera MASM zmienne o
określonej wartości deklaruje się w sekcji .data W tym przypadku zadeklarowana
jest zmienna o nazwie dwSuma typu DWORD, która przechowuje wartość 0.
Kliknij w miejscu przedstawionej
kropki na linijce z invoke ExitProcess, eax. Spowoduje to dodanie breakpointa przed wykonanej tej instrukcji.
Uruchom debugowanie programu klawiszem F5. Wykonanie programu zatrzyma się w
miejscu breakpointa i program nie będzie się dalej wykonywał dopóki nie
zostanie naciśnięty klawisz służący do przejścia do następnej instrukcji.
Na dole, w zakładce Autos będzie
pokazana wartość zmiennej dwSuma. Jeżeli nie masz zakładki Autos możesz ją
dodać w trakcie debugowania z Debug > Windows > Autos
Po naciśnięciu F10 wykona się
instrukcja invoke ExitProcess, eax po czym
program zosatnie zamknięty.
Stałe liczbowe
Stałe liczbowe tworzone są przez
ciąg liczb i oraz przez znak, który może przed nimi występować. Na końcu stałej
liczbowej może występować informacja o wykorzystanym systemie liczbowym.
[{+ | -}] cyfry [system liczbowy]
Opis systemu liczbowego
h
|
Szenastkowy
|
q/o
|
Ósemkowy
|
d
|
Dziesiętny
|
b
|
Binarny
|
r
|
Liczba rzeczywista
|
t
|
Dziesiętna (to samo co d)
|
y
|
Binarna (to samo co y)
|
Przykład użycia
|
System liczbowy
|
10
|
Dziesiętny
|
10d
|
Dziesiętny
|
D9Dh
|
Szesnastkowy
|
11101b
|
Binarny
|
55q
|
Ósemkowy
|
66o
|
Ósemkowy
|
Wyrażenia na liczbach całkowitych
MASM pozwala na wykonanie
podstawowych operacji matematycznych w trakcie tłumaczenia kodu. Te operacje
to:
Operator
|
Nazwa
|
Przykład
|
()
|
Nawiasy
|
(-5)
|
+, -
|
Liczba dodatnia, ujemna
|
+5, -5
|
*, /
|
Mnożenie, dzielenie
|
4*5, 12/4
|
MOD
|
Reszta z dzielenia
|
-1 MOD 5
|
+, -
|
Dodawanie, odejmowanie
|
2 + 2, -3 – (-5)
|
Liczby rzeczywiste
Czyli potocznie zwane liczby
zmiennoprzecinkowe. Reprezentowane są przy pomocy liczb dziesiętnych lub szesnastkowych.
Format takiej liczby to:
[{+ | - }] liczba.[liczba] [E [{+
| -}] liczba
Przykłady
|
5.
|
-4.2
|
-123.4E+08
|
33.E9
|
Znak
Znak to graficzna reprezentacja
wartości bajtu. Znaki przechowywane są jako bajty zakodowane w kodzie ASCII.
Znaki zapisywane są między pojedynczymi lub podwójnymi cudzysłowami ‘a’ lub „A”
Ciąg znaków
Ciąg znaków to ich sekwencja
zapisana między pojedynczymi lub podwójnymi cudzysłowami.
„ABC”
‘DEF’
Można w ciągu znaków korzystać z
cudzysłowów natomiast muszą być one różne od tych otaczających cały ciąg. Np:
„Ala ‘ma’ kota”
‘Ala „ma” kota”
Ciąg znaków w pamięci
reprezentowany jest jako następujące po sobie bajty.
Zarezerwowane słowa
W assembly występują słowa, które
mają określone znaczenie i nie można ich użyć w inny sposób, np. nie można
nazwać zmiennej MOV albo INVOKE. Takimi zarezerwowanymi nazwami są.
- Mnemoniki instrukcji
- Nazwy rejestrów
- Dyrektywy asemblera
- Atrybuty rozmiaru zmiennych. Np. DWORD, WORD, BYTE
- Operatory
- Predefiniowane symbole, np @data
Identyfikatory
Programista nazywając stworzony
przez siebie element programu, np. Zmienna lub funkcję nadają jej nazwę, która
identyfikuje ten element wewnątrz programu. Taki identyfikator musi spełniać
kilka warunków, są nimi:
- Musi zawierać od 1 do 247 znaków
- Nazwy nie rozróżniają wielkości znaków
- Pierwszy znak identyfikatoru musi być literą, podkreślenie, @, ? lub $
- Identyfikator nie może być taki jak jedno z zarezerwowanych słów
Instrukcja
Instrukcja to element programu,
który jest wykonywany po jego uruchomieniu. Instrukcje tłumaczone są przez
asembler na odpowiadające im kody języka maszynowego. Instrukcja składa się z
kilku elementów
- Etykieta (opcjonalna)
- Mnemonik instrukcji (wymagany)
- Operandy (zależy od instrukcji)
- Komentarz (opcjonalny)
Tak wygląda schemat:
[etykieta:] mnemonik [operandy]
[;komentarz]
Etykieta
Etykieta służy do oznaczania
miejsca w kodzie. Każdej etykiecie przypisywany jest miejsca, w którym się
znajduje.
Mnemonik
Krótka nazwa identyfikująca
instrukcję.
Operand
Operandy są to wartości, które
przyjmowane są przez instrukcje.
add
eax, 11
W
tym przypadku operandami instrukcji add są eax oraz 11
Komentarze
Komentarze są bardzo ważne w programowaniu, służą do
opisywania działania kodu, podania autora, daty utworzenia kodu oraz innych
informacji na temat programu.
Wyróżnia się dwa rodzaje komentarzy:
- Komentarz w jednej linii. Oznaczany jest on znakiem ; po którym następuje tresć komentarza.
- Komentarz wieloliniowy. Oznaczany on jest w następujący sposób:
COMMENT !
Jedna linia komentarza
Druga linia komentarza
!
!
Lub
COMMENT
&
Jedna linia komentarza
Druga linia komentarza
&
&
Typy podstawowe
Asembler rozróżnia kilka typów podstawowych, które różnią
się rozmiarem – mogą przechowywać różną ilość danych.
Typ
|
Opis
|
BYTE
|
8-bitowa
liczba naturalna
|
SBYTE
|
8-bitowa
liczba całkowita
|
WORD
|
16-bitowa
liczba naturalna
|
SWORD
|
16-bitowa
liczba całkowita
|
DWORD
|
32-bitowa
liczba naturalna
|
SDWORD
|
32-bitowa
liczba całkowita
|
FWORD
|
48-bitowa
liczba naturalna (far pointer)
|
QWORD
|
64-bitowa
liczba naturalna
|
TBYTE
|
80-bitowa
(10 bajtów) liczba naturalna
|
REAL4
|
32-bitowa
liczba rzeczywista
|
REAL8
|
64-bitowa
liczba rzeczywista
|
REAL10
|
80-bitowa
liczba rzeczywista
|
BYTE i SBYTE
Dane typu BYTE i SBYTE zajmują w pamięci jeden bajt. SBYTE
może być dodatni lub ujemny.
Przykłady zdefiniowania takich zmiennych
zmienna1 BYTE 'A'
zmienna2 BYTE 0
zmienna3 BYTE 255
zmienna4 SBYTE -128
zmienna5 SBYTE +30
|
Wielokrotna inicjalziacja
Grupę bajtów można opisać przy pomocy jednej nazwy. W
takim przypadku identyfikator będzie odwoływał się do adresu pierwszej zmiennej
natomiast reszta będzie dostępna przez offset. Rozmiar offsetu wynosi tyle ile
wielkość zmiennych. W tym przypadku jeden bajt.
lista BYTE 'A', 'B', 'C', 'D'
|
Offset
|
Wartość
|
0000
|
‘A’
|
0001
|
‘B’
|
0002
|
‘C’
|
0003
|
‘D’
|
Zdefiniowane ciągi znaków
Jak już wcześniej wspomniałem, ciąg znaków otoczony jest
cudzysłowami. W tym przypadku na końcu ciągu występuje jeszcze bit zerowy,
który oznacza, że jest to koniec danego ciągu znaków.
tekst1 BYTE "Witaj
swiecie!",0
tekst2 BYTE 'Zegnaj swiecie!',0
|
Nic nie stoi na przeszkodzie, żeby zrobić ciąg znaków,
który zajmuje więcej niz jedną linijkę.
lorem BYTE "Lorem
ipsum dolor sit amet, consectetur adipiscing elit."
BYTE "Maecenas gravida porttitor rutrum. Nam
metus felis, "
BYTE "interdum at euismod vitae, volutpat sit
amet erat."
BYTE "Curabitur sed magna dolor. Vivamus risus
turpis, egestas"
BYTE " a placerat luctus, laoreet et augue.
Vestibulum ultricies "
BYTE "magna in efficitur ullamcorper. Donec
dapibus mattis interdum."
BYTE " Phasellus luctus pellentesque suscipit.
", 0Dh, 0Ah, 0
|
Bajty 0Dh, 0Ah odpowiadają CR/LF czyli przejściu do
następnej linii
Operator DUP
Operator DUP inicjalizuje miejsce
dla wielu elementów. Przykład utworzenia tablicy 10-elementowej typu WORD
zainicjalizowanej do wartości 0.
tablica WORD 10 DUP(0)
|
Deklarowanie niezainicjalizowanych danych
Dyrektywa .DATA? służy do
deklarowania niezainicjalizowanych danych. Podczas definiowania dużej ilości
niezainicjalizowanych danych ta dyrektywa sprawia, że program będzie miał
mniejszy rozmiar
.data
tablica1 DWORD 10
DUP(0) ;40 bajtów
.data ?
tablica2 DWORD 5000 DUP(?) ;20 000 bajtów,
niezainicjalizowane
|
|
.data
tablica1 DWORD 10 DUP(0) ; 40 bajtow
tablica2 DWORD 5000 DUP(?) ; 20 000 bajtów,
niezainicjalizowane
|
W tym przypadku program zajmowałby na dysku 20
tyś bajtów więcej
|
.
OdpowiedzUsuńBycie programistą to nie taka prosta sprawa, najpierw trzeba ukończyć studia http://www.wseiz.pl/pl/studia/wydzial-zarzadzania/informatyka , jednak co trzeba przyznać, to że jest to bardzo perspektywiczny kierunek
OdpowiedzUsuń