Operator OFFSET
Operator OFFSET
położenie zmiennej (lub rozkazu) w pamięci
położenie zmiennej (lub rozkazu) w pamięci
określa się poprzez podanie odległości, liczonej
określa się poprzez podanie odległości, liczonej
we bajtach, zmiennej od początku obszaru
we bajtach, zmiennej od początku obszaru
danych — odległość ta nazywana jest
danych — odległość ta nazywana jest
przesunięciem
przesunięciem
lub
lub
offsetem
offsetem
i można ją wyznaczyć
i można ją wyznaczyć
za pomocą operatora OFFSET
za pomocą operatora OFFSET
przykładowo, adres zmiennej moc_czynna, która
przykładowo, adres zmiennej moc_czynna, która
została zdefiniowana w segmencie danych
została zdefiniowana w segmencie danych
moc_czynna
moc_czynna
dw
dw
800
800
można wpisać do rejestru EBX za pomocą rozkazu
można wpisać do rejestru EBX za pomocą rozkazu
mov
mov
ebx, OFFSET moc_czynna
ebx, OFFSET moc_czynna
Rozkaz LEA (1)
Rozkaz LEA (1)
położenie pewnej lokacji pamięci względem
położenie pewnej lokacji pamięci względem
początku segmentu można także wyznaczyć za
początku segmentu można także wyznaczyć za
pomocą rozkazu LEA, który wyznacza adres
pomocą rozkazu LEA, który wyznacza adres
efektywny rozkazu, czyli położenie lokacji pamięci
efektywny rozkazu, czyli położenie lokacji pamięci
(względem początku danych), na której zostanie
(względem początku danych), na której zostanie
wykonana operacja
wykonana operacja
podany poprzednio przykład można przedstawić
podany poprzednio przykład można przedstawić
w innej postaci
w innej postaci
lea
lea
ebx, moc_czynna
ebx, moc_czynna
Rozkaz LEA (2)
Rozkaz LEA (2)
rozkaz LEA wyznacza adres efektywny w trakcie
rozkaz LEA wyznacza adres efektywny w trakcie
wykonywania programu, podczas gdy wartość
wykonywania programu, podczas gdy wartość
operatora OFFSET obliczana jest w trakcie
operatora OFFSET obliczana jest w trakcie
translacji (asemblacji) programu
translacji (asemblacji) programu
należy zwrócić uwagę, że rozkaz LEA nigdy nie
należy zwrócić uwagę, że rozkaz LEA nigdy nie
odczytuje zawartości lokacji pamięci
odczytuje zawartości lokacji pamięci
Rozkaz LEA (3)
Rozkaz LEA (3)
rozkaz LEA używany jest także w obliczeniach nie
rozkaz LEA używany jest także w obliczeniach nie
zawsze związanych z wyznaczeniem adresu
zawsze związanych z wyznaczeniem adresu
zmiennej, np. można go zastosować do obliczenia
zmiennej, np. można go zastosować do obliczenia
sumy zawartości rejestrów czy mnożenia
sumy zawartości rejestrów czy mnożenia
takie konstrukcje trzeba jednak stosować
takie konstrukcje trzeba jednak stosować
ostrożnie, ponieważ w przypadku rozkazu LEA
ostrożnie, ponieważ w przypadku rozkazu LEA
ewentualny nadmiar nie jest sygnalizowany
ewentualny nadmiar nie jest sygnalizowany
Rozkaz LEA (4)
Rozkaz LEA (4)
obliczenia sumy zawartości rejestrów:
obliczenia sumy zawartości rejestrów:
lea
lea
eax, [ebx + ecx]
eax, [ebx + ecx]
zamiast tradycyjnego rozwiązania
zamiast tradycyjnego rozwiązania
mov
mov
eax, ebx
eax, ebx
add
add
eax, ecx
eax, ecx
mnożenie
mnożenie
lea
lea
eax, [eax + eax
eax, [eax + eax
4]
4]
zamiast tradycyjnego rozwiązania
zamiast tradycyjnego rozwiązania
mov
mov
ebx, 5
ebx, 5
mul
mul
ebx
ebx
Tworzenie kodu
Tworzenie kodu
wykonywalnego programu
wykonywalnego programu
(1)
(1)
przekształcenie kodu źródłowego w asemblerze na
ciągi zero-jedynkowe zrozumiałe przez procesor
realizowane jest w kilku etapach:
1.
asemblacja polega na przekształceniu wierszy
źródłowych programu na ciągi zerojedynkowe, jednak z
pozostawieniem pewnej elastyczności umożliwiającej
późniejsze dołączenie podprogramów bibliotecznych i
innych modułów programowych; kod wygenerowany
przez asembler jest określany jako kod w języku
pośrednim (w systemie Windows jest zapisywany w
pliku z rozszerzeniem .OBJ)
Tworzenie kodu
Tworzenie kodu
wykonywalnego programu
wykonywalnego programu
(2)
(2)
2.
konsolidacja (lub linkowanie) polega na scaleniu
różnych modułów programu, w tym kodu
wytworzonego podczas asemblacji i
podprogramów bibliotecznych do postaci
pojedynczego programu, który zostaje zapisany
w pliku (w systemie Windows z rozszerzeniem
.EXE)
3.
ładowanie stanowi ostatnią fazę translacji
programu: system operacyjny wpisuje program
do pamięci głównej (operacyjnej) i dokonuje
niewielkich zmian kodu w celu dostosowania
programu do aktualnego położenia w pamięci
Tworzenie kodu
Tworzenie kodu
wykonywalnego programu
wykonywalnego programu
(3)
(3)
odpowiednikiem asemblacji w przypadku języków
odpowiednikiem asemblacji w przypadku języków
wysokiego poziomu jest kompilacja — kompilatory
wysokiego poziomu jest kompilacja — kompilatory
używane w systemie Windows generują również
używane w systemie Windows generują również
kod w języku pośrednim (plik .OBJ)
kod w języku pośrednim (plik .OBJ)
Asemblacja programów (1)
Asemblacja programów (1)
asemblacja realizowana jest dwuprzebiegowo: w
asemblacja realizowana jest dwuprzebiegowo: w
każdym przebiegu czytany jest cały plik źródłowy
każdym przebiegu czytany jest cały plik źródłowy
(ściśle: moduł) od początku do końca
(ściśle: moduł) od początku do końca
w pierwszym przebiegu asembler stara się
wyznaczyć ilości bajtów zajmowane przez
poszczególne rozkazy i dane; jednocześnie
asembler rejestruje w słowniku symboli wszystkie
pojawiające się definicje symboli (zmiennych i
etykiet)
w drugim przebiegu asembler tworzy kompletną
wersję tłumaczonego programu określając adresy
wszystkich rozkazów w oparciu o informacje
zawarte w słowniku symboli
Asemblacja programów (2)
Asemblacja programów (2)
w procesie asemblacji programów istotną rolę
w procesie asemblacji programów istotną rolę
odgrywa rejestr programowy (tj. definiowany
odgrywa rejestr programowy (tj. definiowany
przez asembler), zwany
przez asembler), zwany
licznikiem lokacji
licznikiem lokacji
licznik lokacji określa adres komórki pamięci
licznik lokacji określa adres komórki pamięci
operacyjnej, do której zostanie przesłany
operacyjnej, do której zostanie przesłany
aktualnie tłumaczony rozkaz lub dana
aktualnie tłumaczony rozkaz lub dana
po załadowaniu rozkazu lub danej, licznik lokacji
po załadowaniu rozkazu lub danej, licznik lokacji
zostaje zwiększony o ilość bajtów zajmowanych
zostaje zwiększony o ilość bajtów zajmowanych
przez ten rozkaz lub daną
przez ten rozkaz lub daną
w trakcie tłumaczenia pierwszego wiersza licznik
w trakcie tłumaczenia pierwszego wiersza licznik
lokacji zawiera 0
lokacji zawiera 0
Asemblacja programów (3)
Asemblacja programów (3)
jeśli asembler napotka wiersz zawierający
jeśli asembler napotka wiersz zawierający
definicję symbolu, to rejestruje go w słowniku
definicję symbolu, to rejestruje go w słowniku
symboli, jednocześnie przypisując temu
symboli, jednocześnie przypisując temu
symbolowi wartość równą aktualnej zawartości
symbolowi wartość równą aktualnej zawartości
licznika lokacji; ponadto zapisywane są także
licznika lokacji; ponadto zapisywane są także
atrybuty symbolu, jak np. byte, word, itp;
atrybuty symbolu, jak np. byte, word, itp;
Przykład asemblacji fragmentu
Przykład asemblacji fragmentu
programu (1)
programu (1)
gamma
gamma
dw
dw
?
?
beta
beta
db
db
?
?
alfa
alfa
dd
dd
74567H, 885678H, 789H
74567H, 885678H, 789H
dd
dd
0A15FF3H, 89ABH
0A15FF3H, 89ABH
— — — — — — —
— — — — — — —
mov
mov
ebx, 12
ebx, 12
; odjęcie liczby 74567H od EAX
; odjęcie liczby 74567H od EAX
sub
sub
eax,
eax,
alfa
alfa
; wpisanie liczby 885678H do EDX
; wpisanie liczby 885678H do EDX
mov
mov
edx,
edx,
alfa
alfa
+4
+4
; dodanie liczby 89ABH do ESI
; dodanie liczby 89ABH do ESI
add
add
esi,
esi,
alfa
alfa
[ebx]+4
[ebx]+4
Przykład asemblacji fragmentu
Przykład asemblacji fragmentu
programu (2)
programu (2)
po wczytaniu segmentu danych (w którym
po wczytaniu segmentu danych (w którym
zdefiniowano zmienne: gamma, beta, alfa)
zdefiniowano zmienne: gamma, beta, alfa)
słownik symboli zawiera następujące pozycje
słownik symboli zawiera następujące pozycje
alfa
alfa
Dword
Dword
0003 _DATA
0003 _DATA
beta
beta
Byte
Byte
0002 _DATA
0002 _DATA
gamma
gamma
Word
Word
0000 _DATA
0000 _DATA
Przykład asemblacji fragmentu
Przykład asemblacji fragmentu
programu (3)
programu (3)
tłumaczenie rozkazu mov ebx, 12 nie wymaga
tłumaczenie rozkazu mov ebx, 12 nie wymaga
zaglądania do słownika symboli — wystarczy tylko
zaglądania do słownika symboli — wystarczy tylko
zamienić mnemonik mov na odpowiedni kod
zamienić mnemonik mov na odpowiedni kod
binarny, następnie określić kod binarny rejestru
binarny, następnie określić kod binarny rejestru
ebx oraz liczbę 12 przedstawić w postaci 32-
ebx oraz liczbę 12 przedstawić w postaci 32-
bitowej liczby binarnej, co prowadzi do podanego
bitowej liczby binarnej, co prowadzi do podanego
niżej rozkazu 5-bajtowego
niżej rozkazu 5-bajtowego
Przykład asemblacji fragmentu
Przykład asemblacji fragmentu
programu (4)
programu (4)
tłumaczenie następnych rozkazów jest bardziej
tłumaczenie następnych rozkazów jest bardziej
skomplikowane: w celu wyznaczenia pola
skomplikowane: w celu wyznaczenia pola
adresowego asembler musi każdorazowo
adresowego asembler musi każdorazowo
odszukiwać w słowniku symboli wartość
odszukiwać w słowniku symboli wartość
przypisaną nazwie alfa — wartość licznika lokacji
przypisaną nazwie alfa — wartość licznika lokacji
dla obszaru danych w chwili wystąpienia definicji
dla obszaru danych w chwili wystąpienia definicji
zmiennej alfa wynosiła 3, zatem wartość
zmiennej alfa wynosiła 3, zatem wartość
przypisana nazwie alfa wynosi 3
przypisana nazwie alfa wynosi 3
Przykład asemblacji fragmentu
Przykład asemblacji fragmentu
programu (5)
programu (5)
należy zwrócić uwagę, że liczba 3 nie jest tu
należy zwrócić uwagę, że liczba 3 nie jest tu
wartością zmiennej alfa, lecz jej adresem
wartością zmiennej alfa, lecz jej adresem
względem początku obszaru danych
względem początku obszaru danych
dwa następne rozkazy zostaną przetłumaczone
dwa następne rozkazy zostaną przetłumaczone
na poniższą postać binarną
na poniższą postać binarną
Przykład asemblacji fragmentu
Przykład asemblacji fragmentu
programu (6)
programu (6)
zauważmy, że dwa ostatnie rozkazy mają
zauważmy, że dwa ostatnie rozkazy mają
identyczne pole adresowe (cztery ostatnie bajty)
identyczne pole adresowe (cztery ostatnie bajty)
Operacje na liczniku lokacji
Operacje na liczniku lokacji
(1)
(1)
licznikiem lokacji można się także posługiwać w
licznikiem lokacji można się także posługiwać w
programie źródłowym – aktualna zawartość
programie źródłowym – aktualna zawartość
licznika lokacji jest reprezentowana przez symbol
licznika lokacji jest reprezentowana przez symbol
$
$
symbol $ może stanowić operand w wyrażeniach
symbol $ może stanowić operand w wyrażeniach
języka asembler, reprezentujący bieżącą lokację
języka asembler, reprezentujący bieżącą lokację
wewnątrz aktualnie tłumaczonego kodu
wewnątrz aktualnie tłumaczonego kodu
Operacje na liczniku lokacji
Operacje na liczniku lokacji
(2)
(2)
Przykład
Przykład
: podany niżej dwubajtowy rozkaz jmp
: podany niżej dwubajtowy rozkaz jmp
powoduje przejście do następnego rozkazu. Obok
powoduje przejście do następnego rozkazu. Obok
podano postać rozkazu po asemblacji.
podano postać rozkazu po asemblacji.
jmp $+2
jmp $+2
(kod maszynowy: EBH 00H)
(kod maszynowy: EBH 00H)
Czasami tego rodzaju rozkazy umieszcza się w
Czasami tego rodzaju rozkazy umieszcza się w
programie w celu wprowadzenia dodatkowego
programie w celu wprowadzenia dodatkowego
opóźnienia.
opóźnienia.
Operacje na liczniku lokacji
Operacje na liczniku lokacji
(3)
(3)
Przykład:
Przykład:
wykorzystując symbol $ można łatwo
wykorzystując symbol $ można łatwo
wyznaczyć liczbę znaków łańcucha, np.:
wyznaczyć liczbę znaków łańcucha, np.:
blad_par
blad_par
db
db
'Podano błędne parametry’
'Podano błędne parametry’
wiel = $ — blad_par
wiel = $ — blad_par
- - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - -
mov
mov
ecx, wiel
ecx, wiel
Operacje na liczniku lokacji
Operacje na liczniku lokacji
(4)
(4)
wartość wyrażenia $ — blad_par obliczana jest w
wartość wyrażenia $ — blad_par obliczana jest w
trakcie asemblacji programu, a nie w czasie jego
trakcie asemblacji programu, a nie w czasie jego
wykonywania (co jest charakterystyczne dla
wykonywania (co jest charakterystyczne dla
języków wysokiego poziomu) — z tego powodu
języków wysokiego poziomu) — z tego powodu
wyrażenia tego rodzaju nazywane są
wyrażenia tego rodzaju nazywane są
wyrażeniami
wyrażeniami
arytmetycznymi czasu translacji
arytmetycznymi czasu translacji
także zmienna wiel jest
także zmienna wiel jest
zmienną czasu translacji
zmienną czasu translacji
,
,
co oznacza, że dla zmiennej tej nie jest
co oznacza, że dla zmiennej tej nie jest
rezerwowany żaden obszar w programie
rezerwowany żaden obszar w programie
wynikowym
wynikowym
Operacje na liczniku lokacji
Operacje na liczniku lokacji
(5)
(5)
innymi słowy zmienna wiel funkcjonuje jedynie w
innymi słowy zmienna wiel funkcjonuje jedynie w
czasie translacji (asemblacji) programu
czasie translacji (asemblacji) programu
zauważmy, że trakcie asemblacji instrukcji mov
zauważmy, że trakcie asemblacji instrukcji mov
zmienna czasu translacji wiel traktowana jest
zmienna czasu translacji wiel traktowana jest
jako liczba, a nie jako nazwa zmiennej
jako liczba, a nie jako nazwa zmiennej
zdefiniowanej za pomocą dyrektywy DW.
zdefiniowanej za pomocą dyrektywy DW.
Dyrektywa ORG
Dyrektywa ORG
dyrektywa ORG umożliwia wpisanie do licznika
dyrektywa ORG umożliwia wpisanie do licznika
lokacji potrzebnej wartości, np.:
lokacji potrzebnej wartości, np.:
ORG 100H
ORG 100H
w polu operandu dyrektywy ORG można podać
w polu operandu dyrektywy ORG można podać
wyrażenie arytmetyczne czasu translacji, np.
wyrażenie arytmetyczne czasu translacji, np.
dyrektywa
dyrektywa
ORG $+7
ORG $+7
powoduje zwiększenie
powoduje zwiększenie
aktualnej zawartości licznika lokacji o 7
aktualnej zawartości licznika lokacji o 7
Sprawozdanie z
Sprawozdanie z
przebiegu translacji
przebiegu translacji
programu (1)
programu (1)
w trakcie asemblacji tworzony jest plik z
w trakcie asemblacji tworzony jest plik z
rozszerzeniem .LST zawierający obszerne
rozszerzeniem .LST zawierający obszerne
sprawozdanie z jej przebiegu (tzw. listing
sprawozdanie z jej przebiegu (tzw. listing
asemblacji)
asemblacji)
analogicznie w trakcie konsolidacji tworzony jest
analogicznie w trakcie konsolidacji tworzony jest
plik z rozszerzeniem .MAP
plik z rozszerzeniem .MAP
Sprawozdanie z
Sprawozdanie z
przebiegu translacji
przebiegu translacji
programu (2)
programu (2)
w pliku .LST podawane są kolejne wiersze
w pliku .LST podawane są kolejne wiersze
programu źródłowego oraz wygenerowany na ich
programu źródłowego oraz wygenerowany na ich
podstawie kod półskompilowany (ang. object
podstawie kod półskompilowany (ang. object
code); podane są także nazwy i wartości
code); podane są także nazwy i wartości
wszystkich etykiet, zmiennych i symboli
wszystkich etykiet, zmiennych i symboli
stosowanych w programie źródłowym;
stosowanych w programie źródłowym;
sygnalizowane są też ewentualne błędy
sygnalizowane są też ewentualne błędy
poniżej podano przykładowy fragment tego pliku
poniżej podano przykładowy fragment tego pliku
obejmujący trzy rozkazy programu
obejmujący trzy rozkazy programu
Sprawozdanie z
Sprawozdanie z
przebiegu translacji
przebiegu translacji
programu (3)
programu (3)
000000A6
000000A6
8A 03
8A 03
nowy:
nowy:
mov
mov
al, [ebx]
al, [ebx]
000000A8
000000A8
43
43
inc
inc
ebx
ebx
000000A9
000000A9
3C 0A
3C 0A
cmp
cmp
al,10
al,10
w końcowej części sprawozdania podany jest
w końcowej części sprawozdania podany jest
słownik symboli używanych w programie.
słownik symboli używanych w programie.
Kod asemblerowy w
Kod asemblerowy w
wersji AT&T (1)
wersji AT&T (1)
omawiany wcześniej asembler został
omawiany wcześniej asembler został
zaprojektowany przez firmę Intel dla
zaprojektowany przez firmę Intel dla
wytwarzanych przez nią procesorów
wytwarzanych przez nią procesorów
dostępne są także asemblery używające innych
dostępne są także asemblery używające innych
składni języka, spośród których najbardziej znana
składni języka, spośród których najbardziej znana
jest składnia AT&T stosowana w Linuksie
jest składnia AT&T stosowana w Linuksie
Kod asemblerowy w
Kod asemblerowy w
wersji AT&T (2)
wersji AT&T (2)
zasadnicze różnice między tymi asemblerami są
zasadnicze różnice między tymi asemblerami są
następujące:
następujące:
•
nazwy rejestrów poprzedzone są znakiem %
nazwy rejestrów poprzedzone są znakiem %
•
przesłania zapisywane są w postaci
przesłania zapisywane są w postaci
skąd, dokąd
skąd, dokąd
•
prawie każdy rozkaz posiada jawnie zdefiniowany rozmiar
prawie każdy rozkaz posiada jawnie zdefiniowany rozmiar
operandów, określony przez ostatnią literę instrukcji, np.:
operandów, określony przez ostatnią literę instrukcji, np.:
movl (%ebx), %eax
movl (%ebx), %eax
(AT&T)
(AT&T)
mov eax, dword ptr [ebx]
mov eax, dword ptr [ebx]
(Intel)
(Intel)
.
.
Kod asemblerowy w
Kod asemblerowy w
wersji AT&T (3)
wersji AT&T (3)
wartości bezpośrednie są poprzedzone znakiem $, np.
wartości bezpośrednie są poprzedzone znakiem $, np.
movl $1, %ebx
movl $1, %ebx
(AT&T)
(AT&T)
mov ebx, 1
mov ebx, 1
(Intel)
(Intel)
liczby w zapisie szesnastkowym poprzedzone są znakami 0x
liczby w zapisie szesnastkowym poprzedzone są znakami 0x
(tak jak w C)
(tak jak w C)
segmenty programu są deklarowane poprzez nazwy, np.
segmenty programu są deklarowane poprzez nazwy, np.
.text, .bss
.text, .bss
część rozkazów procesora posiada odmienne mnemoniki, np.
część rozkazów procesora posiada odmienne mnemoniki, np.
cwb
cwb
komentarze poprzedzone są znakiem #
komentarze poprzedzone są znakiem #
.
.
Kod asemblerowy w
Kod asemblerowy w
wersji AT&T (4)
wersji AT&T (4)
modyfikacje adresowe stosują dość specyficzną
modyfikacje adresowe stosują dość specyficzną
notację
notację
movl (%ebx), %eax
movl (%ebx), %eax
mov eax, [ebx]
mov eax, [ebx]
movl 3(%ebx), %eax
movl 3(%ebx), %eax
mov eax, [ebx+3]
mov eax, [ebx+3]
mov (%ebx, %ecx), %eax
mov (%ebx, %ecx), %eax
mov eax, [ebx + ecx]
mov eax, [ebx + ecx]
mov (%ebx, %ecx, 2), %eax
mov (%ebx, %ecx, 2), %eax
mov eax, [ebx + ecx*2]
mov eax, [ebx + ecx*2]
Asemblery: za i przeciw (1)
Asemblery: za i przeciw (1)
Od wielu lat trwają dyskusje na temat
Od wielu lat trwają dyskusje na temat
przydatności kodowania programów na poziomie
przydatności kodowania programów na poziomie
asemblera — poniżej wymieniono najczęściej
asemblera — poniżej wymieniono najczęściej
podawane argumenty „za”:
podawane argumenty „za”:
1.
1.
argumenty edukacyjne
argumenty edukacyjne
: można poznać działanie procesora i
: można poznać działanie procesora i
komputera na poziomie rozkazów, można wybrać
komputera na poziomie rozkazów, można wybrać
efektywną technikę kodowania programu;
efektywną technikę kodowania programu;
2.
2.
asembler stanowi pomost łączący sprzęt i oprogramowanie:
asembler stanowi pomost łączący sprzęt i oprogramowanie:
można poznać kody generowane przez kompilatory
można poznać kody generowane przez kompilatory
języków wysokiego poziomu, można identyfikować błędy
języków wysokiego poziomu, można identyfikować błędy
trudne do znalezienia (ang. hard-to-find-errors); znajomość
trudne do znalezienia (ang. hard-to-find-errors); znajomość
techniki kodowania w asemblerze stanowi podstawę do
techniki kodowania w asemblerze stanowi podstawę do
budowy kompilatorów, debuggerów i innych narzędzi;
budowy kompilatorów, debuggerów i innych narzędzi;
Asemblery: za i przeciw (2)
Asemblery: za i przeciw (2)
3.
3.
w
w
systemach wbudowanych
systemach wbudowanych
, ze względu na ich mniejsze zasoby
, ze względu na ich mniejsze zasoby
sprzętowe w porównaniu z PC, stosowanie asemblera może być
sprzętowe w porównaniu z PC, stosowanie asemblera może być
konieczne ze względu na ostre wymagania dotyczące rozmiaru
konieczne ze względu na ostre wymagania dotyczące rozmiaru
programu czy prędkości wykonywania;
programu czy prędkości wykonywania;
4. oprogramowanie
4. oprogramowanie
sterowników urządzeń
sterowników urządzeń
korzysta zazwyczaj z
korzysta zazwyczaj z
rejestrów sterujących, które nie są dostępne w językach wysokiego
rejestrów sterujących, które nie są dostępne w językach wysokiego
poziomu;
poziomu;
5.
5.
kodowanie w asemblerze pozwala na tworzenie kodu
kodowanie w asemblerze pozwala na tworzenie kodu
samomodyfikującego się (aczkolwiek nie jest to zalecane ze względu
samomodyfikującego się (aczkolwiek nie jest to zalecane ze względu
na interferencje z kodem przechowywanym w pamięci podręcznej);
na interferencje z kodem przechowywanym w pamięci podręcznej);
6.
6.
możliwa jest optymalizacja kodu ze względu na rozmiar zajmowanej
możliwa jest optymalizacja kodu ze względu na rozmiar zajmowanej
pamięci i prędkość wykonywania.
pamięci i prędkość wykonywania.
Asemblery: za i przeciw (3)
Asemblery: za i przeciw (3)
argumenty „przeciw”:
argumenty „przeciw”:
1.
1.
czas opracowywania programu jest zazwyczaj bardzo długi;
czas opracowywania programu jest zazwyczaj bardzo długi;
2.
2.
kodowanie w asemblerze jest podatne na błędy, np. rzadko
kodowanie w asemblerze jest podatne na błędy, np. rzadko
wprowadza się kontrolę bilansowania stosu;
wprowadza się kontrolę bilansowania stosu;
3.
3.
identyfikacja błędów w programie jest czasami bardzo
identyfikacja błędów w programie jest czasami bardzo
trudna, mimo stosowania debuggerów;
trudna, mimo stosowania debuggerów;
4.
4.
kod w asemblerze jest w pełni zrozumiały dla autora, dla
kod w asemblerze jest w pełni zrozumiały dla autora, dla
innych osób może być słabo czytelny — utrudnia to
innych osób może być słabo czytelny — utrudnia to
wprowadzanie aktualizacji, szczególnie gdy autor nie pracuje
wprowadzanie aktualizacji, szczególnie gdy autor nie pracuje
już w firmie;
już w firmie;
5.
5.
kod w asemblerze jest dość trudno przenieść na inną
kod w asemblerze jest dość trudno przenieść na inną
platformę sprzętową;
platformę sprzętową;
Asemblery: za i przeciw (4)
Asemblery: za i przeciw (4)
wymienione przyczyny powodują, że kod
wymienione przyczyny powodują, że kod
asemblerowy stanowi zazwyczaj tylko fragment
asemblerowy stanowi zazwyczaj tylko fragment
całego programu i często zawiera operacje
całego programu i często zawiera operacje
krytyczne dla działania całej aplikacji
krytyczne dla działania całej aplikacji
Przekazywanie parametrów
Przekazywanie parametrów
do podprogramów (1)
do podprogramów (1)
A. Sposoby przekazywania
A. Sposoby przekazywania
parametrów:
parametrów:
przekazywanie przez wartość (ang. call by
value) – do podprogramu przekazywana jest
bezpośrednio wartość parametru, którym
może być liczba, tablica liczb, łańcuch
znaków, itp;
przekazywanie przez adres (ang. call by
location) – do podprogramu przekazywany
jest adres lokacji pamięci, w której znajduje
się przekazywana wartość
Przekazywanie parametrów
Przekazywanie parametrów
do podprogramów (2)
do podprogramów (2)
B. Drogi przekazywania parametrów:
B. Drogi przekazywania parametrów:
przez rejestry (w procesorach 64-bitowych,
w procesorach klasy RISC)
przez stos (typowa, powszechnie stosowana
metoda),
przez bufory (tj. przez zarezerwowane
obszary pamięci o ustalonych adresach).
Przekazywanie parametrów
Przekazywanie parametrów
przez stos (1)
przez stos (1)
Przekazywanie parametrów do podprogramów
Przekazywanie parametrów do podprogramów
(procedur, funkcji) przez stos jest powszechnie
(procedur, funkcji) przez stos jest powszechnie
stosowane przez kompilatory opracowane dla
stosowane przez kompilatory opracowane dla
procesorów 32-bitowych
procesorów 32-bitowych
W architekturze 64-bitowej pierwsze cztery
W architekturze 64-bitowej pierwsze cztery
parametry przekazywane są przez rejestry
parametry przekazywane są przez rejestry
procesora, a dopiero ewentualny piąty parametr,
procesora, a dopiero ewentualny piąty parametr,
szósty, itd. przekazywane są przez stos
szósty, itd. przekazywane są przez stos
Technikę przekazywania parametrów przez stos
Technikę przekazywania parametrów przez stos
wyjaśnimy na przykładzie podprogramu
wyjaśnimy na przykładzie podprogramu
suma
suma
,
,
który wyznacza sumę trzech liczb 32-bitowych ze
który wyznacza sumę trzech liczb 32-bitowych ze
znakiem
znakiem
Przekazywanie parametrów
Przekazywanie parametrów
przez stos (2)
przez stos (2)
Przyjmujemy następujące założenia:
Przyjmujemy następujące założenia:
•
parametry, w postaci liczb 32-bitowych ze
parametry, w postaci liczb 32-bitowych ze
znakiem (kod U2), wpisywane są na stos przed
znakiem (kod U2), wpisywane są na stos przed
wywołaniem podprogramu;
wywołaniem podprogramu;
•
obliczona wartość wyrażenia (zakładamy, że
obliczona wartość wyrażenia (zakładamy, że
również 32-bitowa) powinna zostać załadowana
również 32-bitowa) powinna zostać załadowana
do rejestru EAX;
do rejestru EAX;
•
w trakcie wykonywania obliczeń nie wystąpi
w trakcie wykonywania obliczeń nie wystąpi
nadmiar (przepełnienie)
nadmiar (przepełnienie)
•
obowiązek zdjęcia parametrów ze stosu po
obowiązek zdjęcia parametrów ze stosu po
wykonaniu obliczeń należy do podprogramu
wykonaniu obliczeń należy do podprogramu
Przekazywanie parametrów
Przekazywanie parametrów
przez stos (3)
przez stos (3)
Jeśli przykładowe wartości parametrów będą
Jeśli przykładowe wartości parametrów będą
wynosiły 17, –5, 7, to wywołanie podprogramu
wynosiły 17, –5, 7, to wywołanie podprogramu
suma
suma
może mieć postać:
może mieć postać:
push
push
dword PTR 17
dword PTR 17
push
push
dword PTR –5
dword PTR –5
push
push
dword PTR 7
dword PTR 7
call
call
suma
suma
; wywołanie podprogramu
; wywołanie podprogramu
Przekazywanie parametrów
Przekazywanie parametrów
przez stos (4)
przez stos (4)
w wyniku wykonania podanych rozkazów
w wyniku wykonania podanych rozkazów
zawartość stosu będzie następująca:
zawartość stosu będzie następująca:
Odczytywanie parametrów
Odczytywanie parametrów
przez rozkazy wewnątrz
przez rozkazy wewnątrz
podprogramu (1)
podprogramu (1)
odczytywanie parametrów za pomocą rozkazu
odczytywanie parametrów za pomocą rozkazu
POP byłoby kłopotliwe: wymagałoby uprzedniego
POP byłoby kłopotliwe: wymagałoby uprzedniego
odczytania wartości śladu, a po wykonaniu
odczytania wartości śladu, a po wykonaniu
obliczeń należało by ponownie załadować ślad na
obliczeń należało by ponownie załadować ślad na
stos
stos
odczytane parametry można by umieścić w
odczytane parametry można by umieścić w
rejestrach ogólnego przeznaczenia — rejestry te
rejestrach ogólnego przeznaczenia — rejestry te
jednak używane są do wykonywania obliczeń i
jednak używane są do wykonywania obliczeń i
przechowywania wyników pośrednich, wskutek
przechowywania wyników pośrednich, wskutek
czego nadają się do przechowywania jedynie kilku
czego nadają się do przechowywania jedynie kilku
parametrów
parametrów
Odczytywanie parametrów
Odczytywanie parametrów
przez rozkazy wewnątrz
przez rozkazy wewnątrz
podprogramu (2)
podprogramu (2)
w celu zorganizowania wygodnego dostępu do
w celu zorganizowania wygodnego dostępu do
parametrów umieszczonych na stosie przyjęto, że
parametrów umieszczonych na stosie przyjęto, że
obszar zajmowany przez parametry będzie
obszar zajmowany przez parametry będzie
traktowany jako zwykły obszar danych
traktowany jako zwykły obszar danych
w istocie stos jest bowiem umieszczony w
w istocie stos jest bowiem umieszczony w
pamięci głównej (operacyjnej) i nic nie stoi na
pamięci głównej (operacyjnej) i nic nie stoi na
przeszkodzie, by w pewnych sytuacjach traktować
przeszkodzie, by w pewnych sytuacjach traktować
jego zawartość jako zwykłe dane
jego zawartość jako zwykłe dane
Odczytywanie parametrów
Odczytywanie parametrów
przez rozkazy wewnątrz
przez rozkazy wewnątrz
podprogramu (3)
podprogramu (3)
taki niestandardowy dostęp do danych
taki niestandardowy dostęp do danych
zapisanych na stosie wymaga znajomości ich
zapisanych na stosie wymaga znajomości ich
adresów
adresów
trzeba przy tym uwzględnić, że położenie danych
trzeba przy tym uwzględnić, że położenie danych
zapisanych na stosie ustalane jest dopiero w
zapisanych na stosie ustalane jest dopiero w
trakcie wykonywania programu, i może się
trakcie wykonywania programu, i może się
zmieniać przy kolejnych wywołaniach
zmieniać przy kolejnych wywołaniach
podprogramu — konieczne jest więc opracowanie
podprogramu — konieczne jest więc opracowanie
schematu wyznaczania adresów parametrów
schematu wyznaczania adresów parametrów
umieszczonych na stosie, dostosowanego do
umieszczonych na stosie, dostosowanego do
aktualnej sytuacji na stosie
aktualnej sytuacji na stosie
Odczytywanie parametrów
Odczytywanie parametrów
przez rozkazy wewnątrz
przez rozkazy wewnątrz
podprogramu (4)
podprogramu (4)
można zauważyć, że parametry podprogramu
można zauważyć, że parametry podprogramu
odległe są o ustaloną liczbę bajtów od
odległe są o ustaloną liczbę bajtów od
wierzchołka stosu (tu: o 4 bajty, na których
wierzchołka stosu (tu: o 4 bajty, na których
zapisany jest ślad)
zapisany jest ślad)
ponieważ położenie wierzchołka stosu wskazuje
ponieważ położenie wierzchołka stosu wskazuje
rejestr ESP, więc na podstawie zawartości rejestru
rejestr ESP, więc na podstawie zawartości rejestru
ESP można wyznaczyć adresy parametrów, np.
ESP można wyznaczyć adresy parametrów, np.
liczba –5 znajduje się w komórce pamięci o
liczba –5 znajduje się w komórce pamięci o
adresie równym zawartości rejestru ESP
adresie równym zawartości rejestru ESP
powiększonej o 8
powiększonej o 8
z kolei znając adres komórki pamięci można
z kolei znając adres komórki pamięci można
odczytać jej zawartość posługując się
odczytać jej zawartość posługując się
mechanizmem modyfikacji adresowej
mechanizmem modyfikacji adresowej
Pomocniczy wskaźnik stosu
Pomocniczy wskaźnik stosu
EBP (1)
EBP (1)
zawartość rejestru ESP może się zmieniać w
zawartość rejestru ESP może się zmieniać w
trakcie wykonywania podprogramu, konieczne
trakcie wykonywania podprogramu, konieczne
jest użycie innego rejestru, którego zawartość,
jest użycie innego rejestru, którego zawartość,
ustalona przez cały czas wykonywania
ustalona przez cały czas wykonywania
podprogramu, będzie wskazywała obszar
podprogramu, będzie wskazywała obszar
parametrów na stosie — rolę tę pełni, specjalnie
parametrów na stosie — rolę tę pełni, specjalnie
do tego celu zaprojektowany rejestr EBP, często
do tego celu zaprojektowany rejestr EBP, często
nazywany
nazywany
pomocniczym wskaźnikiem stosu
pomocniczym wskaźnikiem stosu
Pomocniczy wskaźnik stosu
Pomocniczy wskaźnik stosu
EBP (2)
EBP (2)
jeśli zawartość rejestru EBP jest równa zawartości ESP, to
jeśli zawartość rejestru EBP jest równa zawartości ESP, to
adres określony przez EBP wskazuje wierzchołek stosu, a
adres określony przez EBP wskazuje wierzchołek stosu, a
EBP zwiększony o 4, 8, 12,... wskazuje kolejne, uprzednio
EBP zwiększony o 4, 8, 12,... wskazuje kolejne, uprzednio
zapisane, wartości 32-bitowe na stosie (należy pamiętać,
zapisane, wartości 32-bitowe na stosie (należy pamiętać,
że stos "rośnie" w kierunku malejących adresów, zatem
że stos "rośnie" w kierunku malejących adresów, zatem
lokacje bardziej odległe od wierzchołka stosu będą miały
lokacje bardziej odległe od wierzchołka stosu będą miały
wyższe adresy)
wyższe adresy)
ponieważ zawartość rejestru EBP jest zazwyczaj
ponieważ zawartość rejestru EBP jest zazwyczaj
potrzebna w programie nadrzędnym, więc przez użyciem
potrzebna w programie nadrzędnym, więc przez użyciem
EBP w podprogramie trzeba zapamiętać jego zawartość
EBP w podprogramie trzeba zapamiętać jego zawartość
na stosie
na stosie
Pomocniczy wskaźnik stosu
Pomocniczy wskaźnik stosu
EBP (3)
EBP (3)
zaraz po tym trzeba wpisać do rejestru EBP
zaraz po tym trzeba wpisać do rejestru EBP
aktualną zawartość rejestru ESP, tak by możliwy
aktualną zawartość rejestru ESP, tak by możliwy
był do parametrów zapisanych na stosie — zatem
był do parametrów zapisanych na stosie — zatem
dwa pierwsze rozkazy podprogramu
dwa pierwsze rozkazy podprogramu
suma
suma
będą
będą
miały postać:
miały postać:
suma
suma
PROC
PROC
push
push
ebp
ebp
; przechowanie EBP na stosie
; przechowanie EBP na stosie
mov
mov
ebp, esp
ebp, esp
; po wykonaniu tego rozkazu, rejestr EBP będzie
; po wykonaniu tego rozkazu, rejestr EBP będzie
; wskazywał wierzchołek stosu
; wskazywał wierzchołek stosu
Pomocniczy wskaźnik stosu
Pomocniczy wskaźnik stosu
EBP (4)
EBP (4)
Aktualna sytuacja na stosie pokazana jest
Aktualna sytuacja na stosie pokazana jest
rysunku
rysunku
Kod podprogramu
Kod podprogramu
suma
suma
suma PROC
push ebp ; przechowanie EBP na stosie
mov ebp,esp ; po wykonaniu tego rozkazu EBP
; będzie wskazywał wierzchoł. stosu
mov eax, [ebp] + 16
add eax, [ebp] + 12
add eax, [ebp] + 8
; wynik obliczeń znajduje się w rejestrze EAX
pop ebp ; odtworzenie EBP
ret12 ; powrót do programu wywołującego
; i usunięcie parametrów ze stosu
suma ENDP