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]

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.

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.

Parametry procedury

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.

Dyrektywa PROTO - przykłady

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

Ekwiwalentny kod ASM

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

•

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

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

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