
- •III Procesor główny
- •Schemat przepływu danych w cpu
- •Najprostszy system połączeń
- •Numery, wartości I adresy kolejnych wyrazów szeregu
- •Instrukcją komplementarną do load jest instrukcja store, której nazwa w mips jest sw (store word). Służy do zapisywania danych w pamięci, a jej format jest taki sam jak instrukcji lw.
- •Potok (strumień) (ang. Flowchart) czynności, które powinna wykonać instrukcja
- •Instrukcja iteracji
- •Inna trudność związana z procedurami w mips jest powodowana przez konieczność umieszczania na stosie zarówno liczb jak I bardziej złożonych struktur danych, na przykład ciągów liczbowych.
- •Operandy mips
- •Instrukcje języka asembler
- •Schemat ilustrujący realizację zbioru instrukcji mips
- •Poprzedni schemat uzupełniony o niektóre linie I urządzenia systemu sterowania
- •1.Nieznana instrukcja lub przepełnienie
- •Składniki komputera zawierające informację o stanie komputera
- •2.Żądanie pobrania informacji z I/o
- •Czasy w pikosekundach (10-9s) trwania każdego z etapów wybranych instrukcji
Numery, wartości I adresy kolejnych wyrazów szeregu
Instrukcją komplementarną do load jest instrukcja store, której nazwa w mips jest sw (store word). Służy do zapisywania danych w pamięci, a jej format jest taki sam jak instrukcji lw.
Przykład
Zapisać w kodzie asemblera polecenie języka C: A(4) = h +A(3), liczba h znajduje się w rejestrze $s2, A oznacza szereg liczbowy. Przyjmiemy tak jak poprzednio, że baza szeregu znajduje się w rejestrze $s3.
W tym wypadku dwa operandy znajdują się w pamięci. Podobnie jak w poprzednim przykładzie pierwsza instrukcja ściąga element szeregu do tymczasowego rejestru, druga dodaje składowe sumy a trzecia przenosi wynik do pamięci
lw $t0,8($s3) # tymczasowy rejestr $t0 zawiera A(3)
add $t0,$s2,$t0 # tymczasowy rejestr $t0 zawiera h +A(3)
sw $t0,12($s3) # 4 wyraz szeregu zawiera sumę h +A(3).
Stałe lub operandy natychmiastowe
Często się zdarza, że program potrzebuje tej samej wielkości wiele razy, na przykład liczby, o którą ma wzrosnąć indeks wyrazy w szeregu danych. Obserwacje pokazują się, że w ponad połowie instrukcji arytmetycznych MIPS jednym z operandów jest stała. Gdyby używać poznanych dotychczas instrukcji trzeba by za każdym razem wywoływać stałą z słowa pamięci RAM, w którym została zapisana podczas ładowania programu. Gdyby stała znajdowała się pod adresem ‘AddrConstant’ odpowiednia instrukcja miałaby postać
lw $t0, AddrConstant($s1) # $t0 = constant.
Zamiast tego w MIPS utworzona została instrukcja specjalnego dodawania ‘addi’ (add immediately) przypisana do każdej stałej. Wówczas powiększenie na przykład wskaźnika znajdującego się w rejestrze $s3 o 4 wykonuje instrukcja
addi $s3,$s3,4 # $s3 = $s3 + 4.
Reprezentacja instrukcji w komputerze
Między postacią instrukcji przekazywanej przez człowieka komputerowi a tym co widzi komputer jest istotna różnica. Po pierwsze instrukcje podobnie jak liczby i inne wielkości przechowywane są w postaci szeregu znaków 0 i 1 które z kolei reprezentują małe i duże wartości napięcia lub ładunku elektrycznego. Zatem również nazwy rejestrów są w ten sposób reprezentowane, czyli są liczbami, a dokładniej wartościami różnicy potencjałów na okładkach kondensatora (a jeszcze dokładniej czy ta różnica jest ‘low’ czy ‘high’) w odpowiednich jednobitowych komórkach pamięci. Konieczne jest odwzorowanie nazw rejestrów na przypisane im numery. Odwzorowanie jest następujące rejestry $s0 do $s7 mają numery 16 do 23, rejestry $t0 do $t7 mają numery 8 do 15.
Przykład
Postać symboliczna instrukcji jest taka add $t0,$s1,$s2. Tabela poniżej podaje różne reprezentacje (format) instrukcji add, umiejscowienie składników w rejestrze przechowującym instrukcję i charakterystyki instrukcji
nr pola w rejestrze |
1 |
2 |
3 |
4 |
5 |
6 |
nazwa pola |
op |
rs |
rt |
rd |
shamt |
funct |
długość pola w bitach |
6 |
5 |
5 |
5 |
5 |
6 |
instrukcja(j.asembler) |
(add) |
$s1 |
$s2 |
$t0 |
|
(add) |
numery rejestru dziesiętnie |
0 |
17 |
18 |
8 |
0 |
32 |
dwójkowo (j. maszynowy) |
000 000 |
10 001 |
10 010 |
01 000 |
00 000 |
100 000 |
numery rejestru szesnastkowo |
0 |
11 |
12 |
8 |
0 |
20 |
Kolejne zbiory bitów, numerowane od lewej nazywają się polami, pola mają nazwy własne. Każdej grupie instrukcji przypisane jest jednoznacznie jedno pole. W rejestrze instrukcja jest reprezentowana przez liczbę, w kodzie asemblera jest to liczba dziesiętna, w kodzie maszynowym jest to liczba binarna, w komentarzach zazwyczaj jest to liczba szesnastkowa. Nazwy mnemoniczne pól częściowo wyjaśniają co się w nich może znajdować:
- op - tradycyjnie nazywane 'opcode' zawiera operację i format instrukcji,
- rs - rejestr źródłowy pierwszego operandu, (source register)
- rt - rejestr źródłowy drugiego operandu, (temporary register)
- rd rejestr przeznaczony na wynik operacji, (destination register)
- shamt - wielkość przesunięcia, wyjaśni się poźniej, (shiftamount)
- funct - uzupełnia informację zawartą w opcode o wariancie operacji (functioncode).
W MIPS wszystkie rejestry mają taką samą długość (32 lub 64 bity). Format opisany powyżej nazywany formatem R (od register) pasuje do większości ale nie do wszystkich instrukcji. Nie zawsze pasuje np. do instrukcji addi, gdyż pięciobitowe pole wystarczy do przechowania stałych mniejszych od 33. Niezbędne jest wprowadzenie innego formatu rejestru o nazwie format I (od słowa immediate). Pola rejestru o formacie I podaje poniższa tabela
nazwa pola |
op |
rs |
rt |
constant lub address |
długość w bitach |
6 |
5 |
5 |
16 |
Pola o numerach 4,5,i 6 zostały połączone w jedno pole o długości 16 bitów i zmienionej nazwie.
Dzięki 16 bitowej długości pola można w nim zapisać liczbę nie większą od 215 lub nie więcej niż 213 słów czterobitowych np. adresu w rejestrze zawierającym bazę szeregu. Teraz instrukcja 'load', która pojawiła się w jednym z przykładów: lw $t0,8($s3) może zostać zastąpiona taką: lw $t0,32($s3). Pole rt pełni teraz rolę taką jak poprzednio rd. Informacja o tym, którą z instrukcji lw należy w danej chwili wykonać, jest przechowywana w pierwszym polu rejestrów zawierających instrukcje, czyli w polu o nazwie op.
Przykład
Chcemy zapisać w kodzie maszynowym polecenie języka C: A(300) = h +A(300). Baza szeregu A znajduje się w rejestrze $s1, liczba h znajduje się w rejestrze $s2.
W języku asemblera odpowiednie trzy instrukcje to
lw $t0,1200($t1) # tymczasowy rejestr $t0 zawiera A(300)
add $t0,$s2,$t0 # tymczasowy rejestr $t0 zawiera h +A(300)
sw $t0,1200($t1) # instrukcja umieszcza sumę h +A(300) w komórce pamięci zawierającej # poprzednio A(300).
Odpowiednie pola w rejestrach instrukcji znajdują się w poniższej tabeli
op |
rs |
rt |
rd |
addres/shamt |
funct |
lw |
$t1 |
$t0 |
1200 |
||
add |
$s2 |
$t0 |
$t0 |
0 |
32 |
sw |
$t1 |
$t0 |
1200 |
Liczba 1200 = 300*4 jest ofsetem w pamięci RAM adresu wyrazu szeregu A o numerze 300.
Tabela poniżej zawiera te same instrukcje w języku maszynowym z użyciem liczb dziesiętnych dla nazw instrukcji i rejestrów
op |
rs |
rt |
rd |
addres/shamt |
funct |
35 |
9 |
8 |
1200 |
||
0 |
18 |
8 |
8 |
0 |
32 |
43 |
9 |
8 |
1200 |
Tabela poniżej zawiera to samo co poprzednia ale używa liczb dwójkowych dla nazw instrukcji i rejestrów
op |
rs |
rt |
rd |
addres/shamt |
funct |
100011 |
01001 |
01000 |
0000 0100 1011 0000 |
||
000000 |
10010 |
01000 |
01000 |
00000 |
100000 |
101011 |
01001 |
01000 |
0000 0100 1011 0000 |
Operacje logiczne w MIPS
Operacja shift
Komputer zazwyczaj wykonuje operacje na całych słowach, jednak czasem wygodnie jest dokonywać operacji na pojedynczych bitach słowa. Przykładem jest analiza tekstu w celu ustalenia jak często pojawiają się w nim poszczególne litery. Służą do tego operacje logiczne stanowiące drugą po operacjach arytmetycznych grupę operacji. Tabelka poniżej podaje listę nazw i oznaczeń instrukcji logicznych w języku C i symbolicznym MIPS
operacja logiczna |
oznaczenie w C |
instrukcja MIPS |
przesunięcie w lewo (shift left logical) |
<< |
sll |
przesunięcie w prawo (shift right logical) |
>> |
srl |
bitowe AND |
& |
and, andi |
bitowe OR |
| |
or, ori |
bitowe NOT |
~ |
nor |
Pierwsze dwie operacje przesunięcia wykonują przesunięcie zawartości wszystkich bitów słowa w lewo lub prawo. Pojawiające się puste bity zostają zapełnione zerami.
Przykład
Rrejestr $s0 zawiera liczbę 0000 0000 10012 = 910.
Po wykonaniu na tym rejestrze operacji przesunięcia w lewo o 4
sll $s0,$s0,4
zawartość rejestru to 0000 1001 00002 = 14410 = 910*24.
Właściwość
podana na końcu poprzedniego wiersza jest ogólna, mianowicie,
jeżeli x2 jest dowolną liczbą binarną to liczba
y2 otrzymana w wyniku przesunięcia w lewo o k
bitów jest równa
.
Teraz można wyjaśnić nazwę 'shamt' jednego z pól rejestru instrukcji typu R, jest to skrót od 'shift amount'. Pole podaje wielkość przesunięcia w bitach jeżeli instrukcją jest przesunięciem. Jeżeli wielkość przesunięcia znajduje się w rejestrze $t0 to w języku maszynowym pola instrukcji sll z powyższego przykładu są takie jak w poniższej tabeli
op |
rs |
rt |
rd |
addres/shamt |
funct |
0 |
16 |
16 |
8 |
4 |
0 |
Przy okazji widać, że kodem instrukcji sll jest 0 zarówno w polu op jak i polu funct.
Opearacja AND
AND ma dwa operandy, jej wynikiem jest wartość logiczna zwykłej funkcji logicznej AND dla każdej pary odpowiadających sobie bitów.
Przykład
Rejestry 32 bitowe $t1 i $t2 zawierają liczbę0000 0000 0000 0000 0000 1101 0000 00002 oraz liczbę
0000 0000 0000 0000 0011 1100 0000 00002. Rejestr $t0 zawiera wynik operacji 0000 0000 0000 0000 0000 1100 0000 00002
and $t0,$t1,$t2 # $t0 = $t1 & $t2.
Instrukcji AND używa się często do sprawdzenia jaką wartość mają wybrane bity pewnego rejestru, np. $t2. W tym celu w wybranym rejestrze np. $t1 wybranym bitom przypisujemy wartości 1 (tworzymy tak zwaną maskę). Wartości tych wybranych bitów w rejestrze $t0 są takie same jak w rejestrze $t2.
Podobnie działają pozostałe bitowe instrukcje logiczne
Instrukcje wyboru
Ważną zaletą komputerów jako narzędzi przetwarzania informacji jest możliwość wyboru przetwarzania jedną z kilku równoległych ścieżek w zależności od wartości pewnej zmiennej. Wśród instrukcji MIPS znajdują się dwie instrukcje wyboru podobne do istniejącej w niektórych językach programowania wysokiego poziomu funkcji 'if....then' .
Pierwsza z nich ma symbol 'beq' ('branch if equal' - gałąź jeżeli równe) i konstrukcję 'beq register1, register2, L1', oznaczającą: jeżeli zawartość rejestrów 1 i 2 jest taka sama to należy wykonać instrukcje oznaczone etykietą (label) L1. Druga o nazwie 'bne' (‘branch if not equal’) o konstrukcji i znaczeniu podobnym jak poprzednia w przypadku gdy zawartość rejestrów 1 i 2 jest różna
Przykład: Kompilacja funkcji 'if..then..else'
W języku C odpowiedni kod ma postać 'if(i==j) f = g + h else f = g - h'.