Wsparcie makroasemblera dla
procedur i budowy blokowej
Mechanizmy organizujące przekazywanie parametrów Mechanizmy organizujące parametry lokalne
Mechanizmy organizujące bloki programu
Dokumentacja procedury
Parametry procedury. Wsparcie makroaseblera
•
Dyrektywa INVOKE zastępuje instrukcję wywołującą procedurę. Umożliwia przekazywanie wielu argumentów.
•
Składnia:
INVOKE nazwa_procedury [, lista_argumentów]
Operator ADDR
• Li
P s
o ta
d _
aj a
e r gu
ws m
k e
a n
ź t
n ó
i w
k ( j
n es
a tr /o
f p
a c
r) j
o
d n
o a
l
z na
mi
ennej, .data
zależnie od modelu pamięci używanego
•Dopuszczalne argumenty (MASM) :
byteVal BYTE 10
przez program:
wordVal WORD 1000h
–Stałe liczbowe i wyrażenia typu
•
model małej pamięci (SMALL):. c1o
6d
- e
ca
błikto
o w
w it
e eg
pr o
zesunięcie
; operandy bezpośrednie:
•
model dużej pamięci (LARGE): 32-
–N
b a
it z
owy
y zm
ad i
r en
s n
( y
s c
e h
gment/przesunięcie)
INVOKE Sub1,byteVal,wordVal
•
model płaskiej pamięci (FLAT): 32-
–Adresy i wyrażenia adresowe
bitowe przesunięcie
; adres zmiennej:
–Nazwy rejestrów
INVOKE Sub2,ADDR byteVal
; nazwa rejestru, wyrażenie całkowite:
INVOKE Sub3,eax,(10 * 20)
; wyrażenie adresowe (operand pośredni) : INVOKE Sub4,[ebx]
Implementacja przekazywania przez wartość
•
Kiedy argument procedury jest przekazywany poprzez wartość, jego kopia wpisywana jest na stos.
Przykład:
.data
myData DWORD 10000h
.code
main PROC
INVOKE Sub1, myData
Makroasembler (MASM) utworzy następujący kod: push myData
call Sub1
Implementacja przekazywania przez odwołanie
•
Kiedy parametr przekazywany jest przez odwołanie, adres parametru zapisywany jest na stosie.
Przykład:
.data
myData WORD 1000h
.code
OFFSET wyraż enie (zwykle symbol
main PROC
zmiennej)– funkcja MASM,
INVOKE Sub1, ADDR myData
wartość =przesunię cie adresu
wzglę dem bieżą cego segmentu
Makroasembler (MASM) utworzy następujący kod: push OFFSET myData
call Sub1
Parametry przekazywane przez odwołanie
Przykład:
•
procedura ArrayFill zapełnia tablicę 16-bitowymi całkowitymi liczbami losowymi
•
Program wywołujący przekazuje adres tabeli i liczbę jej elementów:
.data
ArrayFill może odwoływać się do
count = 100
tabeli nie znaj
array WORD count DUP(?)
ąc jej nazwy:
)
.code
push OFFSET array
ArrayFill PROC
Invoke ArrayFill,
push COUNT
push ebp
ADDR array, COUNT
call ArrayFill
mov ebp,esp
pushad
mov esi,[ebp+12]
mov ecx,[ebp+8]
offs e t(a rra y)
[EBP + 12]
.
count
[EBP + 8]
.
re turn addre s s
ESI wskazuje początek tabeli. Łatwo skonstruować
EBP
EBP
pętlę dostępu do każdego elementu tabeli.
Parametry przekazywane przez odwołanie
Przykład:
•
procedura ArrayFill zapełnia tablicę 16-bitowymi całkowitymi liczbami losowymi
•
Program wywołujący przekazuje adres tabeli i liczbę jej elementów:
.data
ArrayFill może odwoływać się do
count = 100
tabeli nie znaj
array WORD count DUP(?)
ąc jej nazwy:
.code
push OFFSET array
ArrayFill PROC
push COUNT
push ebp
call ArrayFill
mov ebp,esp
pushad
mov esi,[ebp+12]
mov ecx,[ebp+8]
offs e t(a rra y)
[EBP + 12]
.
count
[EBP + 8]
.
re turn addre s s
ESI wskazuje początek tabeli. Łatwo skonstruować
EBP
EBP
pętlę dostępu do każdego elementu tabeli.
w deklaracji procedury dyrektywą PROC
• Dyrektywa PROC deklaruje procedurę z opcjonalną listą parametrów.
• składnia:
label PROC lista_parametrów
• lista_parametrów lista parametrów oddzielonych przecinkami. Składnia parametru:
Nazwa_parametru : typ
typ musi być albo jednym ze standardowych typów ASM (BYTE, SBYTE, WORD, itd.), albo wskaźnikiem do jednego z tych typów.
w deklaracji procedury dyrektywą PROC
• Dopuszczalny alternatywny format (jedna lub więcej linii) :
label PROC,
wymagany przecinek
paramList
• Parametry mogą być w tej samej linii . . .
param-1:type-1, param-2:type-2, . . ., param-n:type-n
• lub w wielu oddzielnych liniach:
param-1:type-1,
param-2:type-2,
. . .,
param-n:type-n
Parametry procedury - przykłady
Przykład 1: procedura AddTwo
Przykład 2: Parametrami FillArray są:
ma dwa parametry, których
•
wskaźnik do macierzy bajtów,
wartości dodaje i przekazuje
•
bajt, którego zawartość
ich sumę w EAX.
należy wpisać do każdego
elementu tablicy,
•
rozmiar tablicy
AddTwo PROC,
FillArray PROC,
val1:DWORD, val2:DWORD
pArray:PTR BYTE, fillVal:BYTE
arraySize:DWORD
mov eax,val1
add eax,val2
mov ecx,arraySize
mov esi,pArray
ret
mov al,fillVal
AddTwo ENDP
L1:
mov [esi],al
inc esi
loop L1
ret
FillArray ENDP
Wsparcie makroasemblera. Dyrektywa PROTO
•
Tworzy prototyp procedury
•
Składnia:
– etykieta PROTO lista_parametrów
•
Definuje prototyp dalej umieszczonej procedury. Informuje asembler ile i jakich argumentów może spodziewać się w definicji procedury (możliwość sprawdzania argumentów przez asembler)
•
Prototyp może znaleźć się w oddzielnym pliku INC., jeżeli wszystkie procedury zdefiniowane na podstawie PROTO są
definiowane przy użyciu PROC (parametry na stosie).
•
Każda procedura wywoływana przez INVOKE musi mieć swój prototyp
•
Pełna definicja procedury może także stanowić własny prototyp Standardowa konfiguracja: PROTO umieszcza się na początku programu źródłowego, INVOKE używa się w segmencie kodu, tekst procedury umieszcza się w dalszej części programu.
1) Umieszczenie PROTO w programie:
MySub PROTO
; prototyp procedury
.code
INVOKE MySub
; call wywołanie procedury
MySub PROC
; tekst procedury
.
.
MySub ENDP
2) Lista argumentów w PROTO:
ArraySum PROTO,
ptrArray:PTR DWORD,
; wskaźnik do tablicy
szArray:DWORD
; rozmiar tablicy
Zmienne procedury. Wsparcie makroasemblera.
Dyrektywa USES
Lista rejestrów używanych przez procedurę
USES lista rejestrów
np.
ArraySum PROC USES esi ecx
...
ArraySum PROC
push esi
push ecx
Makroasembler
.
tłumacząc PROC i RET
.
wygeneruje kod:
pop ecx
pop esi
ret
ArraySum ENDP
Zmienne procedury. Wsparcie makroasemblera Dyrektywa LOCAL
LOCAL symbol [[ [ liczba ] ]] [[: typ]] [[, symbol [[ [ liczba] ]] [[ typ]]]]...
W obrębie procedury (definicja PROC/ENDP) na czas wykonania procedury wytwarza umieszczone na stosie zmienne.
• Symbol może być zmienną prostą lub tablicą („liczba” elementów).
• typ: BYTE, WORD, DWORD , FWORD , QWORD , TBYTE , REAL4 , REAL8 , REAL10
Example
PROC
LOCAL
array[20]:BYTE, POINT:DWORD
.........
bezpośrednio za
RET
dyrektywą PROC
Example
ENDP
BubbleSort PROC
LOCAL temp:DWORD, SwapFlag:BYTE
. . .
ret
re turn addre s s
BubbleSort ENDP
EBP
EBP
Makroasembler (MASM)
utworzy nast
te mp
ępujący
[EBP - 4]
kod źródłowy:
ES P
S wa pFla g
[EBP - 8]
BubbleSort PROC
push ebp
mov ebp,esp
add esp,0FFFFFFF8h
; dodaj -8 do ESP
. . .
mov esp,ebp
likwidacja
pop ebp
zmiennych
ret
lokalnych
BubbleSort ENDP
•
Dyrektywa .MODEL określa dla programu model pamięci i jego parametry (specyfikator języka).
•
Składnia:
.MODEL model_pamię ci [, opcje_modelu]
•
model_pamię ci obejmuje następujące warianty:
– tiny, small, medium, compact, large, huge, flat
•
opcje_modelu zawierają specyfikator języka:
– nazewnictwo procedur
– metody przekazywania parametrów
– NEARSTACK/FARSTACK
Modele pamięci – procesory z segmentacją
•
Model pamięci obrany dla danego programu determinuje liczbę i rozmiary segmentów kodu i danych.
•
Tryb rzeczywisty – modele tiny, small, medium, compact, large, huge.
•
Tryb chroniony – tylko model flat.
Model small: kod < 64 KB, dane (w tym stos) < 64 KB.
Wszystkie przesunięcia 16 bitowe.
Model flat: jeden segment dla kodu i dla danych < 4 GB.
Wszystkie przesunięcia 32 bitowe.
Dyrektywa .MODEL - specyfikatory języka
•
C:
– Argumenty procedury wpisane na stos w odwróconej kolejności (w stosunku do listy)
– Stos jest czyszczony przez program wywołujący
•
pascal
– Argumenty procedury wpisane na stos w kolejności (w stosunku do listy)
– Stos jest czyszczony przez wywołaną procedurę
•
stdcall
– Argumenty procedury wpisane na stos w kolejności odwrotnej (od prawej do lewej)
– Stos jest czyszczony przez wywołaną procedurę
Przygotowanie programu wielomodułowego
•
Podstawowe kroki:
– Utworzenie modułu głównego
– Utworzenie oddzielnych plików źródłowych dla każdej procedury (związanych procedur)
– Utworzenie pliku include zawierającego prototypy procedur zewnętrznych (wywoływanych pomiędzy modułami)
– W module głównym użycie dyrektywy INCLUDE,
aby procedury i prototypy były dostępne
Np. plik sum.inc zawiera prototypy funkcji zewnętrznych: PromptForIntegers PROTO,
ptrPrompt:PTR BYTE,
; wskaźnik łańcucha
ptrArray:PTR DWORD,
; wskaźnik tablicy
arraySize:DWORD
; rozmiar tablicy
ArraySum PROTO,
ptrArray:PTR DWORD,
; wskaźnik tablicy
count:DWORD
; rozmiar tablicy
DisplaySum PROTO,
ptrPrompt:PTR BYTE,
; wskaźnik łańcucha
theSum:DWORD
; suma wyr. tablicy
Wywołanie procedury bibliotecznej
• Użyj dyrektywy INCLUDE
INCLUDE nazwa pliku biblioteki
• Wywołuj instrukcją CALL lub INVOKE. Przed wywołaniem przygotuj parametry.
INCLUDE MyLib.inc
.code
..............
..............
..............
Wsparcie makroasemblera. Procedury
biblioteczne.
Clrscr – czyści ekran konsoli.
SetTextColor – ustawia kolory (tekst, tło) na konsoli wyjściowej.
Gotoxy – ustaw kursor na konsoli.
ReadChar – czyta jeden znak ze stand u wejściowego.
ReadHex - czyta 32-bitową l całkowitą zapisaną hexadecymalnie (zak. CR) ze stand u wejściowego.
ReadInt - czyta 32-bitową l całkowitą ze znakiem zapisaną
decymalnie (zak. CR) ze stand u wejściowego.
Wsparcie makroasemblera. Procedury
biblioteczne.
WriteBin – wypisuje 32-bitową l całk bez znaku do stand u wyjściowego w formacie binarnym.
WriteChar – wypisuje pojedynczy znak na stand u wyjściowe.
WriteDec – wypisuje 32-bitową l całk bez znaku do stand u wyjściowego w formacie dziesiętnym.
WriteHex - wypisuje 32-bitową l całk bez znaku do stand u wyjściowego w formacie hexadecymalnym.
WriteInt - wypisuje 32-bitową l całk ze znakiem do stand u wyjściowego w formacie dziesiętnym.
ReadString - czyta łańcuch (zak. CR) ze stand u wejściowego.
WriteString – zapisuje łańcuch zakończony 0 do stand u wyjściowego.
Crlf – wpisuje sekwencję EOL do stand. u. wyjściowego
Wsparcie makroasemblera. Procedury
biblioteczne.
WaitMsg – wyświetla wiadomość, oczekuje na CR.
GetCommandtail – kopiuje argumenty linii rozkazowej do tablicy bajtów.
DumpRegs – wyświetla EAX, EBX, ECX, EDX, ESI, EDI, EBP, ESP, EFLAGS, EIP (hexadecymalnie). Także flagi: Carry, Sign, Zero, Overflow.
DumpMem - wypisuje zawart. bloku pamięci do stand. u.
wyjściowego (hexadecymalnie).
Wsparcie makroasemblera. Procedury
biblioteczne.
Delay - opóźnia wykonanie programu o podane n milisekund.
Random32 – Generuje 32-bitową liczbę pseudolosową (0 ...
FFFFFFFFh).
Randomize – Startuje generator liczb losowych.
RandomRange – Generuje pseudolosową l całk w określonym zakresie.
Dokumentacja procedury powinna zawierać:
•
Opis wszystkich zadań procedury
•
Opis wejść: lista parametrów wejściowych, określenie ich użycia i wymagań
•
Opis wyników: opis wartości zwracanych przez procedurę
•
Opis wymagań: opcjonalna lista wymagań wstępnych, które muszą być spełnione przed wywołaniem procedury Brak gwarancji, że procedura wywołana bez spełnienia
warunków wstępnych będzie działać.
Dokumentacja procedury - przykład
;---------------------------------------------------------
SumOf PROC
;
; Obl. i zwraca wynik sumy trzech 32-bitowych liczb całk.
; wejścia: EAX, EBX, ECX – trzy liczby całkowite. Mogą być
; ze znakiem lub bez.
; wyjścia: EAX = suma, flagi statusu (Carry,
; Overflow, itd.) zmienione.
; Wymagania: nic
;---------------------------------------------------------
add eax,ebx
add eax,ecx
ret
SumOf ENDP
Dokumentacja procedury - przykład
;---------------------------------------------------------
SumOf PROC
;
; Obl. i zwraca wynik sumy trzech 32-bitowych liczb całk.
; wejścia: EAX, EBX, ECX – trzy liczby całkowite. Mogą być
; ze znakiem lub bez.
; wyjścia: EAX = suma, flagi statusu (Carry,
; Overflow, itd.) zmienione.
; Wymagania: nic
;---------------------------------------------------------
add eax,ebx
add eax,ecx
ret
SumOf ENDP