WYKŁAD 5
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
-Nazwy rejestrów
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
Kiedy argument procedury jest przekazywany poprzez wartość, jego kopia wpisywana jest na stos.
Kiedy parametr przekazywany jest przez odwołanie, adres parametru zapisywany jest na stosie.
OFFSET wyrażenie (zwykle symbol zmiennej)- funkcja MASM, wartość=przesunięcie adresu względem bieżącego segmentu
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,
param-1:type-1, param-2:type-2, . . ., param-n:type-n
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 .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
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
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
..............
..............
..............
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.
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
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).
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 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ć.
Wykład 6
Segmenty programu
Metoda organizowania pamięci odpowiadająca sposobowi korzystania z pamięci przez programistę
• program jest zestawem bloków (segmentów). Blok jest
jednostką logiczną:
program główny
procedura/y
funkcja/e
obiekt/y
zmienne lokalne
zmienne globalne
blok wspólny
stos
tablice
łatwiej zapewnić współdzielenie kodu i ochronę danych
Bity dostępu przypisane do segmentów - ochrona i współdzielenie na poziomie segmentów
Bloki programu
Odnoszą się do fragmentów programu, które mogą być docelowo uporządkowane inaczej w kodzie wynikowym niż występują w programie źródłowym
• Pola danych umieszczone w pobliżu korzystających z nich instrukcji
• stanowiące procedury fragmenty umieszczone w tekście programu głównego Bloki programu - asembler
• Asembler grupuje części kodu/danych, które są rozproszone w programie źródłowym, a posiadają ten sam charakter
- Korzyści:
• Grupowanie zapewnia oszczędność miejsca i krótszy kod
• Dzięki tej funkcjonalności - związane ze sobą dane i kod mogą być umieszczone blisko siebie, dla lepszej czytelności i panowania nad programem
Blok domyślny (bez nazwy) zawiera instrukcje wykonywalne
Blok CDATA zawiera pojedyncze dane (jedno-kilka słów)
Blok CBLKS zawiera dane blokowe (tablice)
Bloki programu - zadanie asemblera
asembler logicznie rearanżuje bloki grupując składowe
• rezultat - odpowiada wynikowi przepisania programu do postaci, w której występują zwarte segmenty
Bloki programu - zadanie asemblera
Asembler używa wielu liczników programu
- dyrektywa USE
• Dyrektywy wyróżniają sekcje, które zostaną załadowane w różne obszary pamięci
• I przejście asemblera
- Każdy blok programu - odrębny LC
- Każda etykieta w bloku - adres względny w stosunku do początku bloku
- Na zakończenie I przejścia, końcowa dla bloku wartość LC = długość bloku
- Asembler może przypisać każdemu blokowi adresy początkowe w pliku wynikowym
• II przejście asemblera
- Adres każdego symbolu może być wyliczony poprzez sumowanie adresu początkowego bloku z adresem względnym symbolu
Bloki programu - asembler/loader
• asembler „wewnętrznie” rearanżuje kod i dane w zwarte bloki
• kod generowany do pliku wynikowego nie musi być fizycznie przeorganizowany - wystarczy, że asembler wpisze właściwy adres początkowy dla każdej sekcji
Dodatkowe korzyści grupowania: duże bloki danych poza obszarem kodu programu
- można zastosować krótsze skoki
Dostęp do danych z różnych segmentów wymaga zmiany (częste?) zawartości rejestru segmentowego ® grupować dane w segmentach
Segmenty
nazwa SEGMENT [[READONLY]] [[align]] [[combine]] [[use]] [[`class']]
……………..
....................
nazwa ENDS
Nazwa: umożliwia grupowanie części segmentu (każda kolejna definicja z tą samą nazwą = kontynuacja segmentu) i określenie adresu
align: BYTE, ALIGN(n), WORD, DWORD, PARA, PAGE
combine: PUBLIC, STACK, COMMON, ATaddress, PRIVATE
Określa porządek wpisywania segmentów z tą samą nazwą do pliku wynikowego
PUBLIC, STACK - przed wpisaniem do pliku wynikowego składowe segmentu są scalane; (STACK pozwala zainicjalizować rejestr SS)
PRIVATE - w pliku wynikowym składowe segmentu nie są scalone
readonly: asembler wykaże błąd, gdy napotka instrukcję zapisującą do segmentu nie zabezpiecza przed zapisaniem w trakcie wykonania programu
use Określa, czy generowany kod ma odpowiadać 16, czy 32- bitowym przesunięciom
-wywołania procedur, powroty
-skoki
class Określa kolejność postępowania z segmentami o różnych nazwach
Segmenty - grupowanie
(1) asembler łączy wszystkie segmenty PUBLIC o tej samej nazwie
(2) po złączeniu wpisuje do pliku wyjściowego w kolejności, jak w programie źródłowym (z adresem początkowym pierwszego składnika segmentu)
(3) konsolidator rearanżuje segmenty. Zaczyna od pierwszego segmentu w pliku, następnie szuka segmentu o tej samej klasie i konsoliduje go, wpisując jako kolejny do pliku .EXE
(4) powtarza kroki dla następnych klas
Użytkownik odpowiedzialny za załadowanie właściwych wartości do rejestrów segmentowych.
Dyrektywa ASSUME:
ASSUME segreg:segloc (nazwa segmentu lub grupy (równoważne wyrażenie))
Asembler wylicza przesunięcia, które wraz z zawartością rej. segment. określają pełny adres. Przesunięcia do danych z innego, niż bieżący, segmentu poprzedza „adresem” tego segmentu
Dyrektywa informuje asembler jaką wartość rej. segment. ustalił użytkownik. Nie generuje kodu ML!
ASSUME zwykle nie potrzebna dla CS (CS automatycznie przypisany do bieżącego segmentu programu.
WYKŁAD 7
Etykiety przy instrukcjach lub polach danych
• Wartością etykiety jest adres przypisany linii programu ASM
Rezerwacja komórek pamięci na zmienne programu
• - zmienne z wartością zainicjalizowaną
• - zmienne bez zainicjalizowanej wartości
• Np. dyrektywy: DB, DW, DQ, DT
Dyrektywa ORG ORG wartość Pośrednio przypisuje wartości symbolom
• Ustawia wskaźnik lokalizacji kodu na wyspecyfikowaną wartość
• definiowanie uprzednie (niemożliwe odwołania w przód)
ORG wartość
Dyrektywa RECORD:
symbol RECORD n_pola:długość [wyrażenie], [n_pola:długość
[wyrażenie]]
Definiuje strukturę o danej nazwie.
Nie dokonuje alokacji
Dyrektywa STRUCT:
symbol STRUCT [alignment] Definiuje strukturę o danej nazwie. Nie dokonuje alokacji deklaracje pól
symbol ENDS Ustala „raster” lokalizacji w pamięci
Flaga Zero ustawiana, gdy wynik wynosi 0.
• Flaga Carry ustawiana, gdy wynik jest zbyt duży (zbyt mały), aby umieścić w lokalizacji docelowej.
• Flaga Sign ustawiana, gdy wynik jest ujemny.
• Flaga Overflow ustawiana, gdy wynik w postaci liczby ze znakiem jest niewłaściwy.
• Flaga Parity ustawiana, gdy wynik zawiera parzystą liczbę 1 (low byte).
• Flaga Auxiliary Carry ustawiana, gdy przeniesienie z bitu 3 na bit 4
Skoki warunkowe
• Warunki odnoszą się do. . .
• - flag
• - równości (argumentów)
• - wyników porównań (bez znaku)
• - wyników porównań (ze znakiem)
skoki: slajdy 15-18
Zastosowanie instrukcji TEST
• Nie modyfikuje operandów; określa stan flagi „Zero”.
• Wartość flagi „Zero” jak dla instrukcji AND
Zastosowanie instrukcji CMP
• Porównuje operand docelowy ze źródłowym
• Wartości flag jak dla odejmowania operandu źródłowego od operandu docelowego; operandy niezmienione.
• Składnia: CMP arg docelowy, arg źródłowy
Użyj BT do przekopiowania bitu do CF
• Składnia: BT symbol, n
• Użyj skoku od CF
Organizacja pętli
Składnia:
LOOP etykieta
Działanie:
• ECX ¬ ECX - 1
• ECX > 0, skok do etykiety
LOOPE etykieta
Instrukcja do wykorzystania, należy powtarzać pętlę w czasie, gdy jedna wartość=drugiej, lecz nie przekroczyć maksymalnej liczby iteracji
LOOPNE etykieta
Instrukcja do wykorzystania, gdy należy powtarzać pętlę maksymalną liczbę razy oczekując na spełnienie pewnego warunku
Struktury warunkowe
• Implementacja struktur warunkowych w ASM
• Blokowe polecenia IF
• Pętle WHILE
• Przełącznik CASE
• Wsparcie makroasemblera (MASM)
• Polecenia blokowe IF
• Pętle WHILE
• Pętle REPEAT
Pętla WHILE jest w rzeczywistości poleceniem IF po którym następuje treść pętli zakończona skokiem bezwarunkowym na początek pętli.
Przełącznik CASE
Przełącznik CASE o następującej składni:
CASE zmienna in
"wzorzec1") polecenie1 ;;
"wzorzec2") polecenie2 ;;
"wzorzec3") polecenie3 ;;
*) polecenie_domyślne
esac
... Porównuje zmienną z wzorcami i po napotkaniu pierwszej zgodności wykonuje odpowiadające polecenie a następnie kończy CASE
Dyrektywy .IF, .ELSE, .ELSEIF, .ENDIF mogą być użyte do utworzenia blokowych poleceń IF.
Makroasembler (MASM) utworzy „ukryty” kod źródłowy składający się z instrukcji, etykiet, CMP i skoków warunkowych.
REPEAT Program pętli jest wykonywany przed sprawdzeniem warunku pętli, umieszczonego po dyrektywie .UNTIL.
WHILE
Warunek pętli sprawdzany jest przed wykonaniem programu pętli. Koniec pętli oznaczony jest dyrektywą .ENDW.
WYKŁAD 9
UNIX/Linux cechy
system wielozadaniowy wyposażony w strumienie (potoki) = mechanizm pozwalający sklejać wyjście jednego programu z wejściem drugiego ® możliwość pisania małych aplikacji, wykonujących pojedyncze zadania, łączonych między sobą za pomocą strumieni.
LINUX = jądro systemu, które odpowiedzialne jest za poprawne działanie komputera:
uruchamianie programów,
przydzielanie/ zwalnianie pamięci,
wysyłanie i odbieranie komunikatów sprzętu.
Jądro w połączeniu z dodatkowym oprogramowaniem niezbędnym do użytkowania tworzy tzw.dystrybucję
Systemy dostępne publicznie
GNU - projektu systemu operacyjnego podobnego do Unixa - GNU (GNU's Not Unix). Pierwszym programem, był korzystający z języka Lisp, edytor GNU Emacs.
GNU GPL (GNU General Public License)
jedna z licencji wolnego oprogramowania
- wolność uruchamiania programu w dowolnym celu
- wolność analizowania, jak program działa i dostosowywania go do swoich potrzeb
- wolność rozpowszechniania niezmodyfikowanej kopii programu
- wolność udoskonalania programu i publicznego rozpowszechniania własnych ulepszeń.
Publiczny dostęp do LINUX'a cd.
Obecnie ® dostęp do jądra na podstawie powszechnej licencji publicznej GNU GPL
Dystrybucje przedmiotem obrotu handlowego
Dystrybucje tworzone są przez różne firmy, lub grupy, posiadają jądro Linuxa oraz zbiór aplikacji i narzędzi systemowych, wraz z instalatorem, niezbędnych do prawidłowego działania.
Składowe systemu LINUX slajd 6
Biblioteki
do nich odwołują się programy użytkowe (nie bezpośrednio do funkcji jądra); ukrywają szczegóły implementacyjne zależne od architektury.
Np.:
- zamawianie usług jądra
- zaawansowane sterowanie plikowymi operacjami wejściawyjścia
- inne (nie mają odpowiedników w funkcjach jądra): sortowanie,
funkcje matematyczne, operacje na łańcuchach
Jądro składa się z modułów, które po skompilowaniu zajmują jedną przestrzeń adresową (cały kod jądra, system plików, oprogramowanie sieci)
Moduł realizuje określoną funkcję (np. steruje pracą urządzenia, jest systemem plików, protokołem sieciowym) na rzecz bieżącego procesu.
Ładowany i konsolidowany (usuwany i rozłączany) dynamicznie ® łatwa modyfikacja (zmiana tylko modułu, kompilacja, udostępnianie kodu modyfikacji)
Zarządzanie modułami wprowadzanie do pamięci i kontakt z innymi modułami (tablice symboli zewnętrznych, konsolidacja dynamiczna)
- zamawianie modułu (procedura informowania o zapotrzebowaniu)
- ładowanie modułu (ładowanie i konsolidacja)
Rejestracja modułów sterujących informacja o dostępności
- w jądrze dynamiczne tablice dostępnych modułów + narzędzia do wprowadzania i usuwania wpisów
Rozwiązywanie konfliktów rezerwowanie zasobów, ochrona zasobów przed użyciem przez inny moduł
Koncepcja procesu
Linux = system wieloprogramowy; wiele realizacji programów może być wykonywanych jednocześnie ® proces
Cechy procesu
realizacja wykonywania programu
wykonanie/wstrzymanie w dowolnym momencie
równoległość - przełączanie kontekstowe
niezależność: wykorzystanie mechanizmów CPU dla zapobieżenia bezpośredniego korzystania z hardware'u lub komórek o ustalonych adresach
- tryb użytkownika i tryb jądra
- ochrona pamięci
Procesy w LINUX'ie
Składowe procesu w systemie LINUX
Liniowa przestrzeń adresowa, w której wydzielić można sekcję tekstu (kod programu), sekcję danych i sekcję stosu.
Licznik programu wskazujący na aktualnie wykonywaną instrukcję, lub w przypadku programów wielowątkowych wiele takich liczników.
Zapis stanu rejestrów procesora.
Deskryptory plików, opisujące otwarte przez proces pliki, strumienie i połączenia sieciowe.
Dane procesu, takie jak unikalny dla procesu numer PID, numer użytkownika UID, numery grup GID, efektywny UID i GID..
Zależności rodzinne z innymi procesami: rodzic, lista dzieci i braci.
Liczniki statystyczne zapisujące m.in. zużyty czas w trybie jądra i trybie użytkownika.
Stany procesu
- Aktywny:
-- w trybie użytkownika - proces znajduje się „w procesorze” i wykonuje swój kod.
-- w trybie jądra - jądro wykonuje wywołanie systemowe wykonane przez proces.
- Gotowy do wykonania - może być uruchomiony w każdej chwili, jednak nie został mu jeszcze przydzielony procesor.
- Uśpiony - proces czeka na jakieś zdarzenie, na przykład na odczyt danych z dysku lub z sieci.
- Zatrzymany - proces czeka sygnał (wznowienia)
- Zombie (widmo)- proces zakończył działanie i czeka na odebranie kodu powrotu przez proces, który w międzyczasie przestał istnieć.
Zmiany stanu procesu slajd 17
Przełączanie kontekstowe
- zapisz zawartość rejestrów CPU do deskryptora procesu
- odczytaj zawartość rejestrów CPU z deskryptora następ- nego procesu
Rejestry zachowywane przy przełączaniu
- licznik programu i wskaźnik stosu
- rejestry robocze (ogólnego przeznaczenia)
- rejestry jednostki zmiennoprzecinkowej
- PSW
- rejestry zarządzania pamięcią
Tryb jądra i tryb użytkownika
CPU pracuje w trybie jądra lub w trybie użytkownika
programy w trybie użytkownika nie mają dostępu do przestrzeni danych jądra i funkcji jądra
programy w trybie jądra mają dostęp do wszystkich
zasobów
Wątki
Wątek (thread):
klasa procesu = odrębny strumień wykonawczy działający wewnątrz tego samego procesu. Proces może wykonywać kilka swoich części z uwzględnieniem ograniczeń systemu.
Przykład:
Edytor tekstu może równocześnie dzielić dokument na strony i jednocześnie sprawdzać pisownię.
Cechy wątków:
nie obciążają systemu kosztami związanymi z inicjacją przestrzeni adresowej.