W01 AK2 Biernat


Architektura komputerów 2
Prof. PWr dr hab. inż. Janusz Biernat
Wykład 01
MODELE PROGRAMOWE I JZYKI ASEMBLEROWE
Najbardziej podstawowym zapisem algorytmu jest ciąg zerojedynkowy, bo jest akceptowany
bezpośrednio przez procesor. Jego wygoda jednak jest średnia.
Pierwszy kompilator powstał w roku 1956. Kompilator to program tłumaczący treść algorytmu w
pewnej formie opisu środowiska (czyli w formie tekstowej - międzynarodowym kodzie ASCII,
dzisiaj też UTF-8, np. Java) na treść wynikową, która sama z siebie nie jest jeszcze programem.
Jako że niewygodnym byłoby to, żeby kompilator tworzył gotowy program - ze względu na to, że
niemożliwe byłoby wtedy łączenie niezależnych modułów programów
Kompilator: treść programu (plik zródłowy) + opis środowiska w formie tekstowej
|| (międzynarodowa część kodu ASCII:
treść wynikowa 00
16-7F
16
(plik wynikowy) czyli cyfry dziesiętne
(to nie jest jeszcze program) i znaki alfabetu łacińskiego)
Kompilator zajmuje się tylko sprawdzeniem formalnej poprawności zapisu algorytmu w danym
języku. Nie sprawdza w ogóle semantyki i jego ogólnej sensowności.
Konsolidator: łączenie modułów (treści wynikowych) w tzw. plik wykonywalny nagłówek z
(linker) informacjami dodatkowymi (co można, czego nie można robić z kodem) + kod.
Program ładujący: 1) skopiowanie kodu pliku wykonywalnego do pamięci głównej (z
(w tej chwili której korzysta procesor).
podanie nazwy 2) przekazanie sterowania (skok) do pierwszej instrukcji.
pliku wywołuje
automatycznie
program ładujący)
Plik zródłowy:
(nieprzenoszalny) (przenoszalny)
" zapis algorytmu model programowy procesora / maszyny wirtualnej,
" dyrektywy dla kompilatora konstrukcja kompilatora i środowiska.
W językach asemblerowych dużych programów już się nie pisze. Co najwyżej jakieś małe ich
elementy, albo sterowniki.
Model programowy procesora  wyszczególnienie dostępnych zasobów procesora (ograniczenie
dotyczy dostępu do rejestrów specyficznych). Dostępne są dwa poziomy : użytkownika i nadzoru.
Wszystkie zasoby procesora dostępne są tylko w tym drugim - na przykład reguły wzajemnej
komunikacji procesów, ustawianie rejestrów specjalnych, zmiana zasad ochrony pamięci. Model ten
składa się z następujących trzech podstawowych elementów :
" rejestrów,
" listy rozkazów,
" słów w pamięci operacyjnej.
Wskazywanie dostępu do listy rozkazów i rejestrów jest podobne w architekturach Intel 8086, Intel
IA32 i Intel Pentium. Występują jednak dwa modele pamięci, czyli pamięć liniowa i pamięć
segmentowana.
Model programowy:
nr. segmentu=0
lista rozkazów pamięć główna
adres=0
rejestry (procesor) (słowa w pamięci)
adres w
segmencie
Modele pamięci:
Pamięć liniowa (używana na laboratorium)  łatwiejsza, wirtualny model
pamięci (wszystkie segmenty w jednym miejscu).
Pamięć segmentowa  trudniejsza, Intel odwołuje się do tego modelu:
wskaznik / adres
nr. segmentu : adres w segmencie
intel 8086 IA32 PENTIUM
Wyrażenie:
(dyrektywa kompilatora)
opis działania i argumentów według ustalonej składni:
mnemonik argument , argument
(skrót nazwy działania) swobodny akumulacyjny
add (nowa wykładnikowa (stała, zródłowa
adc zawartość) zawartość)
sub arg_akumul := arg_akumul działanie arg_swobodny
...
(argument zapisany w mnemoniku)
rozgałęzienie_warunek adres docelowy
(mnożnik)
mul argument (mnożnik zawsze zawartość rejestru a)
Specyfikacja argumentów:
najwyżej jeden argument może być słowem w pamięci.
Rodzaje:
stałe:
- deklaracja (stałe symboliczne): NAZWA = (typ) lista wartości (jest to deklaracja statyczna i
obowiązują w całym programie)
- użycie jako argumentu: $NAZWA
$0xFC  stała szesnastkowa
$0q75  stała ósemkowa
$0b01  stała dwójkowa
$0d59  stała dziesiętna
59  stała dziesiętna
przy stałych liczbowych musi być podany system (chyba, że stała jest dziesiętna)
(deklaracja dynamiczna EQU)
rejestry: 31 15 8 7 1
a |________|____|____|
ecl  nie ma
b *h *l
ecx !!
c _________
w niektórych
cx
d *x
instrukcjach zawiera
cl
(*) __________________
domniemany
ch
e*x
argument (czasami
si
si 31 15 1
też w d, a w jednym
esi
bp |_________|________|
przypadku w c)
sp **
(**) __________________
e**
użycie rejestrów: %nazwa_rejestru %eax, jeżeli napiszemy bez % kompilator
potraktuje to jako zmienną albo
etykietę, a wtedy może być ciężko
znalezć błąd.
wskazanie słów w pamięci (zmiennych):
zmienne:
- deklaracja
nazwa_zmiennej typ lista_wartości (może być też bufor czyli zmienne bez
wartości początkowej)
.byte, .ascii, .word, .short, ...
-atrybuty
- adres (w prawdziwej architekturze Intela jest on podwójny, bo segment i
przesunięcie w segmencie)
- wartość
- typ
- rozmiar (zawsze w bajtach)
- użycie zmiennych
nazwa_zmiennej (wartość słowa wskazanego przez tą zmienną)
$nazwa_zmiennej (adres zmiennej)
zmienne indeksowane:
nazwa_zmiennej(%rejestr) - indeksowanie za pomocą jednego wskaznika bez skalowania
nazwa_zmiennej(%rejestr_b, %rejestr_indeksowany, skala)
(bazowy, (skalowany) (1,2,4,8)
nieskalowany)
adres_faktyczny=%nazwa_zmiennej+(rejestr_b)+[rejestr_indeksowany*skala]
nazwa_zmiennej(, %rejestr-indeksowany, skala)
W tym ostatnim trybie współczynnik skali określa, o ile bajtów się przesunąć przy jednym  cyklu ,
tj. ile bajtów zajmuje nasze słowo w pamięci.
.align 32  dyrektywa porządkująca (tak ustaw, żeby adres był podzielny przez 32)
JOLA .ascii  Architektura komputerów\n
eax=5, ecx=2 4( ) - $ nie musi być
JOLA(%eax,%ecx,1) 5+2*1 $0xF( ) - $ musi być koniecznie!
rozgałęzienia:
j warunek adres_docelowy (jedna z etykiet w treści programu)
"stan wskaznika z rejestru flag CF C-carry, Z-zero, S-sign, OV-overflow,
NC-notcarry, NZ-notzero, NS-notsign
"wynik porównania - najbardziej sensownym warunkiem wydaje się być
porównanie dwóch liczb. Możemy tego dokonać wykonując instrukcję
cmp X,Y (przy czym pózniejsze warunki to zawsze Y (warunek) X), a
następnie skok w zależności od wyniku tego porównania :
- liczb naturalnych A-above, B-below, E-eqal
- liczb rzeczywistych GT-graterthen, LT-lessthen, E-eqal,
GE-greateroreqal, LE-lessoreqal
loop etykieta
1) zmniejsz ecx
2) sprawdz czy ecx=0
3) TAK  skok do etykiety, NIE  kontynuuj


Wyszukiwarka