Architektura Komputerów/Wykład 3: Synteza modelu programowego: Różnice pomiędzy wersjami
Z Studia Informatyczne
Przejdź do nawigacjiPrzejdź do wyszukiwania
Nie podano opisu zmian |
mNie podano opisu zmian |
||
(Nie pokazano 4 wersji utworzonych przez jednego użytkownika) | |||
Linia 1: | Linia 1: | ||
<hr width="100%"> | <hr width="100%"> | ||
{| border="0" cellpadding="4" width="100%" | |||
|valign="top" width="500px"|[[Grafika:ASK_M3_S01.png]] | |||
|valign="top"| | |||
|}<hr width="100%"> | |||
{| border="0" cellpadding="4" width="100%" | {| border="0" cellpadding="4" width="100%" | ||
|valign="top" width="500px"|[[Grafika:ASK_M3_S02.png]] | |valign="top" width="500px"|[[Grafika:ASK_M3_S02.png]] | ||
Linia 17: | Linia 21: | ||
Głównym celem projektantów pierwszych komputerów było uzyskanie urządzenia, które byłoby w stanie działać bezawaryjnie wystarczająco długo, aby wykonać potrzebne obliczenia. Czasy międzyawaryjne pierwszych komputerów nie przekraczały kilkudziesięciu minut, a ich struktura logiczna była podporządkowana uwarunkowaniom implementacyjnym. | Głównym celem projektantów pierwszych komputerów było uzyskanie urządzenia, które byłoby w stanie działać bezawaryjnie wystarczająco długo, aby wykonać potrzebne obliczenia. Czasy międzyawaryjne pierwszych komputerów nie przekraczały kilkudziesięciu minut, a ich struktura logiczna była podporządkowana uwarunkowaniom implementacyjnym. | ||
Wkrótce po upowszechnieniu komputerów ustabilizowały się metody ich programowania. Obecnie powszechnie używa się języków wysokiego poziomu - proceduralnych i obiektowych. Współczesne komputery są budowane z myślą o programowaniu ich w takich właśnie językach, a ich struktura logiczna jest zaprojektowana tak, aby mogły one łatwo i wydajnie wykonywać | Wkrótce po upowszechnieniu komputerów ustabilizowały się metody ich programowania. Obecnie powszechnie używa się języków wysokiego poziomu - proceduralnych i obiektowych. Współczesne komputery są budowane z myślą o programowaniu ich w takich właśnie językach, a ich struktura logiczna jest zaprojektowana tak, aby mogły one łatwo i wydajnie wykonywać programy powstałe przez translację zapisu algorytmów w językach wysokiego poziomu. | ||
Pomimo odrębnych paradygmatów programowania, języki obiektowe od strony implementacji nie różnią się znacząco od języków proceduralnych. Możny przyjąć, że komputer, który daje się efektywnie programować w języku C będzie podobnie skutecznie wykonywał programy napisane w innych podobnych językach proceduralnych i obiektowych, takich jak np. Pascal, C++ czy Java. | Pomimo odrębnych paradygmatów programowania, języki obiektowe od strony implementacji nie różnią się znacząco od języków proceduralnych. Możny przyjąć, że komputer, który daje się efektywnie programować w języku C będzie podobnie skutecznie wykonywał programy napisane w innych podobnych językach proceduralnych i obiektowych, takich jak np. Pascal, C++ czy Java. | ||
Linia 172: | Linia 176: | ||
|valign="top" width="500px"|[[Grafika:ASK_M3_S19.png]] | |valign="top" width="500px"|[[Grafika:ASK_M3_S19.png]] | ||
|valign="top"| | |valign="top"| | ||
|} | |} | ||
Linia 192: | Linia 196: | ||
|valign="top" width="500px"|[[Grafika:ASK_M3_S21.png]] | |valign="top" width="500px"|[[Grafika:ASK_M3_S21.png]] | ||
|valign="top"| | |valign="top"| | ||
|} | |} | ||
Linia 246: | Linia 250: | ||
|valign="top" width="500px"|[[Grafika:ASK_M3_S27.png]] | |valign="top" width="500px"|[[Grafika:ASK_M3_S27.png]] | ||
|valign="top"| | |valign="top"| | ||
... | Do adresowania ramki stosu można posłużyć się rejestrem wskaźnika ramki. Zawartość wskaźnika ramki, w przeciwieństwie do zawartości wskaźnika stosu, nie zmienia się podczas wykonania ciała procedury. | ||
Wskaźnik ramki wskazuje ramkę bieżącej procedury. Oznacza to, że każda procedura ustanawia własną wartość wskaźnika ramki. Każda procedura spodziewa się również, że jej wartość wskaźnika ramki nie zostanie zmieniona. Oznacza to, że procedura musi przed powrotem odtworzyć wskaźnik ramki procedura wołającej. | |||
|} | |} | ||
Linia 253: | Linia 259: | ||
|valign="top" width="500px"|[[Grafika:ASK_M3_S28.png]] | |valign="top" width="500px"|[[Grafika:ASK_M3_S28.png]] | ||
|valign="top"| | |valign="top"| | ||
|} | |} | ||
Linia 260: | Linia 266: | ||
|valign="top" width="500px"|[[Grafika:ASK_M3_S29.png]] | |valign="top" width="500px"|[[Grafika:ASK_M3_S29.png]] | ||
|valign="top"| | |valign="top"| | ||
... | Po wprowadzeniu wskaźnika ramki możemy wskazać odwzorowanie modelu procesora w rzeczywisty model programowy procesorów rodziny x86, używanych w komputerach PC. Procesory x86 posiadają 8 rejestrów uniwersalnych ( w tym główny akumulator EAX, wskaźnik stosu ESP i wskaźnik ramki EBP) oraz rejestr licznika instrukcji oznaczony symbolem EIP. | ||
Większość instrukcji występuje w postaci dwuargumentowej, a w zapisie symbolicznym instrukcji jako pierwszy podaje się argument docelowy, a następnie argumenty źródłowe. W instrukcjach arytmetycznych i logicznych argument docelowy jest jednocześnie pierwszym argumentem źródłowym. | |||
Procesory x86 umożliwiają adresowanie pamięci sumą zawartości rejestru i stałej (przemieszczenia). Taki tryb adresowania jest wygodny do adresowania obiektów w ramce stosu. Możliwe jest adresowanie zarówno względem wskaźnika stosu, jak i względem wskaźnika ramki. | |||
|} | |} | ||
Linia 267: | Linia 277: | ||
|valign="top" width="500px"|[[Grafika:ASK_M3_S30.png]] | |valign="top" width="500px"|[[Grafika:ASK_M3_S30.png]] | ||
|valign="top"| | |valign="top"| | ||
... | Tabela zawiera zestawienie instrukcji modelu II i ich odpowiedników w x86. instrukcje LOAD i STOR są zastąpione pojedynczą, dwuargumentową instrukcją przesłania MOV. | ||
Operacje CREATE i DESTROY są realizowane jako odjęcie i dodanie stałej określającej rozmiar obiektów do wskaźnika stosu. | |||
|} | |} | ||
Linia 274: | Linia 286: | ||
|valign="top" width="500px"|[[Grafika:ASK_M3_S31.png]] | |valign="top" width="500px"|[[Grafika:ASK_M3_S31.png]] | ||
|valign="top"| | |valign="top"| | ||
... | Składnia zapisu przykładowego programu jest zgodna z asemblerami rodziny NASM. | ||
Sekwencja wywołania dla x86 jest taka sama, jak w dotychczasowych modelach. | |||
Alokacja i dealokacj zmiennej r w procedurze wywoływanej polega na wykonaniu prostej operacji na wskaźniku stosu. Podczas wykonania ciała procedury wskaźnik stosu wskazuje zmienną r. Dostępy do obiektów lokalnych są realizowane przy użyciu adresowania względem wskaźnika stosu. | |||
Po powrocie z procedury następuje usunięcie argumentów. Polega ono na przesunięciu wskaźnika stosu o rozmiar argumentów – w tym przypadku o 8 (dwa argumenty po 32 bity). | |||
Wartość funkcji zostaje zapamiętana w zmiennej statycznej x. Zapis [x] oznacza komórkę pamięci o adresie x. Ponieważ x jest zmienną statyczną, jej adres jest stałą. która może zostać zapisana symbolicznie. | |||
|} | |} | ||
Linia 281: | Linia 301: | ||
|valign="top" width="500px"|[[Grafika:ASK_M3_S32.png]] | |valign="top" width="500px"|[[Grafika:ASK_M3_S32.png]] | ||
|valign="top"| | |valign="top"| | ||
... | W wersji korzystającej ze wskaźnika ramki w prologu procedura następuje zapamiętanie wskaźnika ramki procedury wołającej i ustanowienie własnej wartości wskaźnika ramki. Ostatnia instrukcja prologu służy do alokacji zmiennej lokalnej. | ||
Można zauważyć, że każda procedura będzie miała niemal identyczny prolog, zawierający trzy instrukcje. Jedyna różnica pomiędzy różnymi procedurami polega na odmiennych rozmiarach alokowanych zmiennych lokalnych. | |||
Rysunek przedstawia ramkę stosu procedury podczas wykonywania ciała procedury. pomiędzy śladem powrotu i zmiennymi lokalnymi znajduje się zapamiętany wskaźnik ramki procedury wołającej. Na rysunku zaznaczono adresy poszczególnych obiektów ramki stosu liczone względem rejestru wskaźnika ramki (EBP). | |||
Epilog każdej procedury jest identyczny i zawiera trzy instrukcje. Począwszy od modelu 80186 dwie instrukcje (MOV ESP, EBP; POP EBP) mogą być zastąpione pojedynczą, bezargumentową instrukcją LEAVE. | |||
|} | |} | ||
Linia 288: | Linia 314: | ||
|valign="top" width="500px"|[[Grafika:ASK_M3_S33.png]] | |valign="top" width="500px"|[[Grafika:ASK_M3_S33.png]] | ||
|valign="top"| | |valign="top"| | ||
... | Ponieważ odwołania do pamięci są wolne, we współczesnych procesorach często stosuje się inne implementacje stosu, nie wymagające ciągłych odwołań do pamięci. Jedna lub kilka ramek stosu może zostać umieszczonych w rejestrach procesora. Ponieważ możliwość taka dotyczy tylko obiektów skalarnych określonych typów, w praktyce takie rozwiązanie powoduje istotne komplikacje w przekazywaniu argumentów i alokacji zmiennych lokalnych. Problemem tym zajmuje się jednak kompilator, a programista nie musi być świadomy stopnia komplikacji programu wynikowego. | ||
|} | |} | ||
<hr width="100%"> | <hr width="100%"> |
Aktualna wersja na dzień 17:27, 2 mar 2009
![]() |
![]() |
Wywołanie procedury jest realizowane przez pierwsze trzy instrukcje. Rysunek pokazuje zawartość stosu bezpośrednio po wykonaniu instrukcji skoku ze śladem. |
![]() |
![]() |
![]() |