Wykład 5
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]
•Lista_argumentów jest opcjonalna
•Dopuszczalne argumenty (MASM) :
–Stałe liczbowe i wyra
ż
enia typu
całkowitego
–Nazwy zmiennych
–Adresy i wyra
ż
enia adresowe
–Nazwy rejestrów
.data
byteVal BYTE 10
wordVal WORD 1000h
.code
; operandy bezpo
ś
rednie:
INVOKE Sub1,byteVal,wordVal
; adres zmiennej:
INVOKE Sub2,ADDR byteVal
; nazwa rejestru, wyra
ż
enie całkowite:
INVOKE Sub3,eax,(10 * 20)
; wyra
ż
enie adresowe (operand po
ś
redni) :
INVOKE Sub4,[ebx]
Operator ADDR
Podaje wska
ź
nik (near/far) do zmiennej,
zale
ż
nie od modelu pami
ę
ci u
ż
ywanego
przez program:
•
model małej pami
ę
ci (SMALL): 16-
bitowe przesuni
ę
cie
•
model du
ż
ej pami
ę
ci (LARGE): 32-
bitowy adres (segment/przesuni
ę
cie)
•
model płaskiej pami
ę
ci (FLAT): 32-
bitowe przesuni
ę
cie
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
push myData
call Sub1
Makroasembler (MASM) utworzy nast
ę
puj
ą
cy kod:
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
main PROC
INVOKE Sub1, ADDR myData
push OFFSET myData
call Sub1
Makroasembler (MASM) utworzy nast
ę
puj
ą
cy kod:
OFFSET wyra
ż
enie (zwykle symbol
zmiennej)– funkcja MASM,
warto
ść
=przesuni
ę
cie adresu
wzgl
ę
dem bie
żą
cego segmentu
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
count = 100
array WORD count DUP(?)
.code
push OFFSET array
push COUNT
call ArrayFill
Parametry przekazywane przez odwołanie
ArrayFill mo
ż
e odwoływa
ć
si
ę
do
tabeli nie znaj
ą
c jej nazwy:
ArrayFill PROC
push ebp
mov ebp,esp
pushad
mov esi,[ebp+12]
mov ecx,[ebp+8]
.
.
offs e t(a rra y)
count
EBP
[EBP + 8]
[EBP + 12]
re turn addre s s
EBP
ESI wskazuje pocz
ą
tek tabeli. Łatwo skonstruowa
ć
p
ę
tl
ę
dost
ę
pu do ka
ż
dego elementu tabeli.
.data
count = 100
array WORD count DUP(?)
.code
Invoke ArrayFill,
ADDR array, COUNT
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
count = 100
array WORD count DUP(?)
.code
push OFFSET array
push COUNT
call ArrayFill
Parametry przekazywane przez odwołanie
ArrayFill mo
ż
e odwoływa
ć
si
ę
do
tabeli nie znaj
ą
c jej nazwy:
ArrayFill PROC
push ebp
mov ebp,esp
pushad
mov esi,[ebp+12]
mov ecx,[ebp+8]
.
.
offs e t(a rra y)
count
EBP
[EBP + 8]
[EBP + 12]
re turn addre s s
EBP
ESI wskazuje pocz
ą
tek tabeli. Łatwo skonstruowa
ć
p
ę
tl
ę
dost
ę
pu do ka
ż
dego elementu tabeli.
Parametry procedury
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.
• Dopuszczalny alternatywny format (jedna lub wi
ę
cej linii) :
label PROC,
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
wymagany przecinek
Parametry procedury
w deklaracji procedury dyrektywą PROC
Parametry procedury - przykłady
AddTwo PROC,
val1:DWORD, val2:DWORD
mov eax,val1
add eax,val2
ret
AddTwo ENDP
FillArray PROC,
pArray:PTR BYTE, fillVal:BYTE
arraySize:DWORD
mov ecx,arraySize
mov esi,pArray
mov al,fillVal
L1:
mov [esi],al
inc esi
loop L1
ret
FillArray ENDP
Przykład 2: Parametrami FillArray s
ą
:
•
wska
ź
nik do macierzy bajtów,
•
bajt, którego zawarto
ść
nale
ż
y wpisa
ć
do ka
ż
dego
elementu tablicy,
•
rozmiar tablicy
Przykład 1: procedura AddTwo
ma dwa parametry, których
warto
ś
ci dodaje i przekazuje
ich sum
ę
w EAX.
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
Dyrektywa PROTO - przykłady
ArraySum PROTO,
ptrArray:PTR DWORD,
; wska
ź
nik do tablicy
szArray:DWORD
; rozmiar tablicy
2) Lista argumentów w PROTO:
Zmienne procedury. Wsparcie makroasemblera.
Dyrektywa USES
USES lista rejestrów
np.
ArraySum PROC USES
esi ecx
...
ArraySum PROC
push esi
push ecx
.
.
pop ecx
pop esi
ret
ArraySum ENDP
Lista rejestrów u
ż
ywanych przez procedur
ę
Makroasembler
tłumacz
ą
c PROC i RET
wygeneruje kod:
Zmienne procedury. Wsparcie makroasemblera
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
Dyrektywa LOCAL
Example
PROC
LOCAL
array[20]:BYTE, POINT:DWORD
.........
RET
Example
ENDP
bezpo
ś
rednio za
dyrektyw
ą
PROC
Ekwiwalentny kod ASM
BubbleSort PROC
LOCAL temp:DWORD, SwapFlag:BYTE
. . .
ret
BubbleSort ENDP
BubbleSort PROC
push ebp
mov ebp,esp
add esp,0FFFFFFF8h
; dodaj -8 do ESP
. . .
mov esp,ebp
pop ebp
ret
BubbleSort ENDP
Makroasembler (MASM)
utworzy nast
ę
puj
ą
cy
kod
ź
ródłowy:
re turn addre s s
EBP
EBP
[EBP - 4]
ES P
te mp
S wa pFla g
[EBP - 8]
likwidacja
zmiennych
lokalnych
Dyrektywa .MODEL
•
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
Plik INCLUDE – przykład
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
Np. plik sum.inc zawiera prototypy funkcji zewn
ę
trznych:
Wywołanie procedury bibliotecznej
INCLUDE MyLib.inc
.code
..............
..............
..............
• U
ż
yj dyrektywy INCLUDE
INCLUDE nazwa pliku biblioteki
• Wywołuj instrukcj
ą
CALL lub INVOKE. Przed wywołaniem
przygotuj parametry.
Clrscr
– czy
ś
ci ekran konsoli.
SetTextColor
– ustawia kolory (tekst, tło) na konsoli wyj
ś
ciowej.
Gotoxy
– ustaw kursor na konsoli.
Wsparcie makroasemblera. Procedury
biblioteczne.
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.
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.
Wsparcie makroasemblera. Procedury
biblioteczne.
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
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.
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
•
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
Dokumentacja procedury powinna zawiera
ć
:
Brak gwarancji,
ż
e procedura wywołana bez spełnienia
warunków wst
ę
pnych b
ę
dzie działa
ć
.
;---------------------------------------------------------
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
Dokumentacja procedury - przykład