Wykład 4
Programowanie modułowe w j
ę
zyku
asemblera
Programowanie modułowe
Proc1
Proc2
Proc3
Proc1-3
Proc1-2
Proc1-1
Proc2-3
Proc2-2
Proc2-1
Proc3-3
Proc3-2
Proc3-1
Prog
Programowanie modułowe
1.3) zaciśnij palce na uchu
1.2) sięgnij ręką do ucha filiżanki
1.1) rozewrzyj palce
0) pij z filiżanki
1) chwyć filiżankę za ucho
2) podnieś filiżankę do ust
3) wlej zawartość do gardła
2.2) przysuń rękę poziomo do ust
2.1) unieś rękę do góry
3.3) POŁYKAJ PŁYN!!!
3.2) przechyl filiżankę
3.1) otwórz usta
Budowa programu z procedurami
•
Dekompozycja funkcjonalna (od góry do dołu) :
– zaprojektuj program przed programowaniem
– podziel du
ż
e zadania na mniejsze
– u
ż
yj struktury hierarchicznej opartej na procedurach
– poszczególne procedury testuj oddzielnie
S umma tion
P rogra m (ma in)
Clrs cr
P romptForInte ge rs
Arra yS um
Dis pla yS um
Write S tring
Write S tring
Re a dInt
Write Int
Write Int
Definiowanie i używanie procedur
• Budowanie procedur
• Instrukcje wywołania i powrotu
• Etykiety lokalne i globalne
• Parametry procedur
• Zmienne lokalne
Definiowanie procedury
Proc1
Proc1-3
Proc1-2
Proc1-1
Prog
na przykład
ZEROBYTES:
XOR
AX, AX
MOV
CX, 128
ZEROLOOP:
MOV
[BX], AX
ADD
BX, 2
LOOP ZEROLOOP
RET
ZEROBYTES zeruje 256
bajtów począwszy od adr
w BX
NAZWA_PROCEDURY:
tre
ść
procedury
...................
tre
ść
procedury
RET
Parametry!!!
Zwykle procedura
wymaga danych
ZEROBYTES:
PROC
XOR AX, AX
JCXZ DOFFS
ZEROLOOP:
MOV [BX], AX
ADD BX, 2
LOOP ZEROLOOP
RET
DOFFS:
MOV CX, 128
MOV AX, 0FFFFH
FFLOOP:
MOV [BX], AX
SUB BX, 2
LOOP FFLOOP
RET
ZEROBYTES:
ENDP
Jedna procedura czy dwie?
(ZEROBYTES, DOFFS)
Jeden punkt wej
ś
cia czy
dwa?
Definiowanie procedury
XOR AX, AX
JCXZ DOFFS
ZEROLOOP:
MOV [BX], AX
ADD BX, 2
LOOP ZEROLOOP
RET
DOFFS:
MOV CX, 128
MOV AX, 0FFFFH
FFLOOP: MOV [BX], AX
SUB BX, 2
LOOP FFLOOP
RET
Definiowanie procedury
Jedna procedura czy dwie?
(ZEROBYTES, DOFFS)
Jeden punkt wej
ś
cia czy
dwa?
ZEROBYTES:
PROC
ZEROBYTES:
ENDP
dyrektywy
PROC
ENDP
usuwaj
ą
niejednoznaczno
ść
Definicja procedury:
ProcName
proc {near|far}
<instrukcje procedury>
ProcName
endp
Procesory z segmentacj
ą
(Intel x86)
CALL
RETN
CALL FAR PTR symbol
RETF
na stosie tylko przesuni
ę
cie
Definiowanie procedury
na stosie CS i przesuni
ę
cie
(przesuni
ę
cie:segment)
Wi
ę
cej o PROC przy omawianiu parametrów
Procedury zagnieżdżone
Procesory z segmentacj
ą
(Intel x86)
OutsideProc proc near
….......
InsideProc proc near
. …......
InsideProc endp
….......
OutsideProc endp
cseg segment
..............
MyProc proc near
Ret
MyProc endp
..............
cseg
ends
Etykiety lokalne i globalne
main PROC
jmp L2
; bł
ą
d
L1::
; etykieta globalna
exit
...........
...........
sub2 PROC
L2:
; etykieta lokalna
jmp L1
; ok
ret
sub2 ENDP
main ENDP
Lokalna etykieta widoczna tylko dla polece
ń
w obr
ę
bie danej
procedury. Etykieta globalna jest widoczna wsz
ę
dzie w
programie.
Parametery procedury
•
Dobra procedura powinna by
ć
u
ż
yteczna w wielu ró
ż
nych
programach
– nie b
ę
dzie, je
ż
eli odwołuje si
ę
do ustalonych nazw
zmiennych
•
Parametry umo
ż
liwiaj
ą
elastyczno
ść
procedur – warto
ś
ci
parametrów mog
ą
zmienia
ć
si
ę
w czasie wykonywania
programu
ArraySum PROC
mov esi,0
; wska
ź
nik tablicy
mov eax,0
; wst
ę
pnie suma=0
mov ecx,
LENGTHOF myArray
;liczba elementów tablicy
L1: add eax,
myArray
[esi]
; dodaj ka
ż
dy wyraz do sumy
add esi,4
; wska
ż
nast
ę
pny wyraz
loop L1
; powtarzaj size
mov
theSum
,eax
; wynik do theSum
ret
ArraySum ENDP
Procedura ArraySum oblicza sum
ę
32-bitowych wyrazów tablicy (liczby
całkowite). Odwołuje si
ę
do 2 nazw zmiennych:
myArray, theSum
Procedura nieprzydatna, gdy trzeba j
ą
wykonywa
ć
dla wielu tablic!!!
Parametery procedury
Klasyfikacja parametrów
•
Parametr wej
ś
ciowy przekazywany do procedury
:
– Wywoływana procedura nie b
ę
dzie modyfikowa
ć
zmiennej
odpowiadaj
ą
cej temu parametrowi (ew. modyfikacja nie b
ę
dzie
widzialna poza procedur
ą
).
•
Parametr wej
ś
ciowo-wyj
ś
ciowy
jest wska
ź
nikiem do zmiennej
zawieraj
ą
cej warto
ść
, która zarówno b
ę
dzie u
ż
ywana jak i
modyfikowana przez procedur
ę
:
• Zmienna przekazana do procedury jest modyfikowana przez
procedur
ę
.
•
Parametr wyj
ś
ciowy
utworzony jest poprzez przekazanie wska
ź
nika do
zmiennej wraz z wywołaniem procedury:
• Procedura nie wykorzystuje warto
ś
ci zmiennej; przed zako
ń
czeniem
wykonywania procedura wpisuje do tej zmiennej wynikow
ą
warto
ść
.
Przykład
Swap PROC USES eax esi edi,
pValX:PTR DWORD,
; wska
ź
nik do pierwszej zmiennej
pValY:PTR DWORD
; wska
ź
nik do drugiej zmiennej
mov esi,pValX
; pobierz wska
ź
niki
mov edi,pValY
mov eax,[esi]
; pobierz wart. pierwszej zmiennej
xchg eax,[edi]
; zamie
ń
z drug
ą
mov [esi],eax
; zast
ą
p wart. pierwszej zmiennej
ret
Swap ENDP
Procedura Swap wymienia warto
ś
ci dwóch 32-bitowych zmiennych
całkowitych.
pValX
i
pValY
(wska
ź
niki do zmiennych)
nie zmieniaj
ą
warto
ś
ci
. Zmianie podlegaj
ą
zmienne wskazywane przez wska
ź
niki:
Przekazywanie parametrów do i z procedury
5 podstawowych mechanizmów przekazywania danych
• poprzez warto
ść
• poprzez odwo
ł
anie
• poprzez zwrócon
ą
warto
ść
• poprzez rezultat
• poprzez nazw
ę
tylko wej
ś
ciowe
; procedura nie zmienia warto
ś
ci
parametrów – kopiowanie wewn
ą
trz procedury
wska
ź
nik do zmiennej (adres)
przekazywany wska
ź
nik do zmiennej, warto
ść
zmiennej kopiowana do zmiennej wewn. (mog
ą
mie
ć
ró
ż
n
ą
wart.). Wyj
ś
cie - warto
ść
wyniku.
jw.; przekazywanie wył
ą
cznie parametru
wyj
ś
ciowego (nie potrzebne kopiowanie przy
wej
ś
ciu).
Wska
ź
nik do funkcji obliczaj
ą
cej adres zmiennej
rejestry
komórki pami
ę
ci
----
(globalne)
blok
kod programu
stos
Przekazywanie parametrów do procedury
...............
BLOCK1_ADDR EQU 00AA9988H
BLOCK2_ADDR EQU 00AA9988H
..............
MOV BX, #BLOCK1_ADDR
CALL ZEROBYTES
..............
MOV BX, #BLOCK1_ADDR
CALL ZEROBYTES
..................
END
ZEROBYTES:
XOR
AX, AX
MOV
CX, 128
ZEROLOOP:
MOV
[BX], AX
ADD
BX, 2
LOOP ZEROLOOP
RET
Mała liczba rejestrów!!!
ArraySum PROC
; Wej
ś
cia: ESI wska
ź
nik tabeli słów podwójnej długo
ś
ci,
; ECX = liczba elementów tablicy
; Wyj
ś
cie: EAX = suma
;-----------------------------------------------------
mov eax,0
; wst
ę
pnie suma=0
L1: add eax,[esi]
; dodaj ka
ż
dy wyraz do sumy
add esi,4
; wska
ż
nast
ę
pny wyraz
loop L1
; powtarzaj
ret
ArraySum ENDP
Ta wersja ArraySum wyznacza sum
ę
32-bitowych elementów
tablicy, której adres podany jest w ESI. Wynik sumy w EAX.
Przekazywanie parametrów do procedury
Mo
ż
na wielokrotnie wywoływa
ć
dla
ró
ż
nych warto
ś
ci parametrów
Przekazywanie parametrów do procedury
...............
BLOCK1_ADDR EQU 00AA9988H
BLOCK2_ADDR EQU 00AA9988H
..............
MOV PARAM, #BLOCK1_ADDR
CALL ZEROBYTES
..............
MOV PARAM, #BLOCK2_ADDR
CALL ZEROBYTES
..................
END
PARAM:
DW
?
ZEROBYTES:
MOV
BX,PARAM
XOR
AX, AX
MOV
CX, 128
ZEROLOOP:
MOV
[BX], AX
ADD
BX, 2
LOOP ZEROLOOP
RET
Rejestry
Komórki pami
ę
ci
----
(globalne)
blok
kod programu
Stos
Przekazywanie parametrów do procedury
Rejestry
Komórki pami
ę
ci
----
(globalne)
blok
kod programu
Stos
Parametry umieszczone w bloku
komórek pami
ę
ci (jak dla
przekazywania w pami
ę
ci).
Wska
ź
nik do bloku przekazany w
rejestrze lub na stosie
Call disp
DB “This parameter is in the code stream.”,0
.................
Disp PROC NEAR
push bp
mov bp, sp
.............. (m.in. zapisz rejestry na stos)
mov bx, 2[bp] ;adr powrotu do BX
................
(BX zmienia si
ę
, a
ż
wskazuje
adres za ko
ń
cem danych)
mov 2[bp], bx ;nowy adres powrotu na stos
.............. (m.in. czytaj rejestry ze stosu)
pop bp
ret
disp endp
Mo
ż
liwe zmienne o
zmiennej długo
ś
ci
Przekazywanie parametrów do procedury
Rejestry
Komórki pami
ę
ci
----
(globalne)
blok
kod programu
Stos
Parametry na stosie czy w rejestrach?
•
Parametry w rejestrach wymagaj
ą
przeznaczenia po rejestrze na
parametr. U
ż
ycie stosu jest
wygodniejsze.
•
Przykład dwóch ró
ż
nych sposobów
wywołania procedury DumpMem:
pushad
mov esi,OFFSET array
mov ecx,LENGTHOF array
mov ebx,TYPE array
call DumpMem
popad
push OFFSET array
push LENGTHOF array
push TYPE array
call DumpMem
prostszy
Rejestry
Komórki pami
ę
ci
----
(globalne)
blok
kod programu
Stos
Przekazywanie parametrów do procedury
push par1
push par2
push par3
call MyProc
MyProc proc near
pop RtnAdrs16
pop Par3
pop Par2
pop Par1
push RtnAdrs16
.
.
.
ret
CallProc
endp
MyProc(par1,par2,par3);
Parametry na stosie
Przykład: procedura z
3-ma parametrami:
Wywołanie procedury:
MyProc proc near
pop RtnAdrs32
pop Par3
pop Par2
pop Par1
push RtnAdrs32
.
.
.
ret
CallProc
endp
Odczytanie parametrów w
procedurze
ra
m
k
a
Bezpośredni dostęp do parametrów na stosie
•
bezpo
ś
redni dost
ę
p do parametrów na stosie z u
ż
yciem przesuni
ę
cia w
stosunku do EBP (BP – tryb rzeczywisty).
– np: [ebp + 8]
•
EBP – wska
ź
nik bazowy (wska
ź
nik ramki) = adres bazowy ramki na stosie.
•
EBP nie zmienia warto
ś
ci w czasie procedury.
•
Na zako
ń
czenie procedury przywróci
ć
wej
ś
ciow
ą
warto
ść
EBP.
.data
sum DWORD ?
.code
push 6
; drugi argument
push 5
; pierwszy argument
call AddTwo
; EAX = suma
mov sum,eax
; zapisz sum
ę
00000006
00000005
re turn addre s s
EBP , ES P
[EBP + 4]
[EBP + 8]
[EBP + 12]
EBP
AddTwo PROC
push ebp
mov ebp,esp
.
. (dost
ę
p do stosu z u
ż
yciem ebp)
.
Przykład:
Ramka na stosie – cd przykładu
AddTwo PROC
push ebp
mov ebp,esp
; adres bazowy ramki
mov eax,[ebp + 12] ; drugi argument (6)
add eax,[ebp + 8]
; pierwszy argument (5)
mov esp,ebp
pop ebp
ret
AddTwo ENDP
; EAX zawiera sum
ę
inc esp
.........
inc esp
00000006
00000005
re turn addre s s
EBP , ES P
[EBP + 4]
[EBP + 8]
[EBP + 12]
EBP
{
8
×
↔
↔
↔
↔
instrukcja
leave
↔
↔
↔
↔
Instrukcja
ret 8
•
Odczytanie parametrów ze stosu
•
Przywrócenie warto
ś
ci esp i ebp
•
Usuni
ę
cie ramki ze stosu
Przekazywanie parametrów do procedury
Ramka z parametrami procedury
2) Wykonanie procedury wymaga u
ż
ycia rejestrów procesora (wykonywanie
rozkazów)
- te same rejestry mog
ą
by
ć
w u
ż
yciu w programie wywołuj
ą
cym
procedur
ę
-
konflikt!!!
1) Wykonanie procedury mo
ż
e wymaga
ć
u
ż
ycia zmiennych (pomocniczych)
- rejestry procesora
- komórki pami
ę
ci
Inne, równoległe wywołanie procedury spowoduje u
ż
ycie tych samych
rejestrów i komórek pami
ę
ci -
konflikt!!!
• gdzie w pami
ę
ci zlokalizowa
ć
zmienne procedury?
• jak „powieli
ć
” lokalizacje zmiennych dla kolejnych wywoła
ń
procedury?
• jak odwoływa
ć
si
ę
do zmiennych procedury?
Zmienne (lokalne, wewnętrzne) procedury
Zmienna lokalna jest tworzona, u
ż
ywana i likwidowana w
ramach pojedynczej procedury (jest tymczasowa).
Ramka na stosie – przykład Intel
•
Obszar na stosie przeznaczony na: adres powrotu, przekazywane
parametry, zachowane rejestry, zmienne lokalne
• Tworzony w nast
ę
puj
ą
cych krokach:
–program wywołuj
ą
cy umieszcza
argumenty na stosie i wywołuje
procedur
ę
.
–Wywołana procedura zapisuje EBP
na stos i przepisuje ESP do EBP.
–Je
ż
eli potrzebne s
ą
zmienne
lokalne
odpowiednia
liczba
całkowita
odejmowana jest od ESP
,
aby utworzy
ć
miejsce na stosie.
Zmienne wewnętrzne procedury
Ramka ze zmiennymi wewn
ę
trznymi procedury
Przykład: zmienne wewnętrzne procedury -
rekursja
•
Proces powstaj
ą
cy gdy . . .
– procedura wywołuje sam
ą
siebie
– Procedura A wywołuje procedur
ę
B, która wywołuje
procedur
ę
A
•
Rekursja tworzy cykl (patrz ilustracja graficzna)
A
B
D
E
C
Problem: rekursywne
wywołanie – równocze
ś
nie
u
ż
ywane te same parametry
Rekursywne obliczanie sumy
CalcSum PROC
cmp ecx,0
; sprawd
ź
wart. licznika
jz L2
; ko
ń
cz, gdy zero
add eax,ecx
; gdy nie, dodaj do sumy
dec ecx
; zmniejsz licznik
call CalcSum
; wywołaj rekursywnie
L2: ret
CalcSum ENDP
Procedura CalcSum rekursywnie oblicza sum
ę
elementów tablicy
(całkowite). Wej
ś
cie: ECX = liczba. Wyj
ś
cie: EAX = suma
Ramka na stosie:
12
n
n-1
R e turnMain
e bp
0
11
R e turnFact
e bp
1
10
R e turnFact
e bp
2
9
R e turnFact
e bp
3
n-2
n-3
(e tc...)
mov esp,ebp
pop ebp
ret 8
Instrukcja: ENTER (Make Stack Frame, 80286+)
Instrukcja tworzy ramkę na stosie dla procedury używającej parametrów
własnych zlokalizowanych na stosie.
Składnia:
ENTER immed16, 0
ENTER immed16, 1
ENTER immed16, immed8
Ramka na stosie – przykład Intel
Liczba bajtów do zarezerwowania.
Immed16=0
↔
ENTER = push bp,
mov bp,sp.
Maksymalny poziom
zagnie
ż
d
ż
enia
Parametry wyników z procedury
•
Rejestry
•
Stos
•
Pami
ęć
(blok)
return
result
....
przed opuszczeniem procedury
stos
result1
result2
....
zwykle wska
ź
nik do bloku (rejestr
lub stos) + tablica w pami
ę
ci
ptr