1 Ogolnie o asemblerach 2 Zarys architektury MIPS

Transkrypt

1 Ogolnie o asemblerach 2 Zarys architektury MIPS
1
Ogolnie o asemblerach
Kod zerojedynkowy jakim posªuguje si¦ komputer jest niewygodny dla czªowieka. Pomysª: wprowadzenie symbolicznych nazw instrukcji, odzieli¢ pola argumentów. Wci¡» jest niewygodnie, bo musimy podawa¢ rzeczywiste
adresy. Kolejny pomysª: wprawadzenie adresów symbolicznych (etykiet). Otrzymany j¦zyk programowania to
asembler.
Proces produkowania pliku wykonywalnego:
1. Program napisany w j¦zyku asemblerowym jest tªumaczony przez program równie» nazywany asemblerem
na j¦zyk maszynowy (zerojedynkowy). Powsteje
object le plik, który oprócz kodu zawiera dodatkowe
informacje przydatne przy skªadaniu programu z kilku plików. W tej cz¦±ci wylicza si¦ adresy (wymaga
to zazwyczaj dwukrotnego przejrzenia pliku ¹ródªowego).
2. Linkowanie program linkuj¡cy ª¡czy object les i biblioteki programowe, z których korzysta program
w jeden plik wykonywalny. Tak naprawd¦, plik wykonywalny równie» nie zawiera jeszcze adresów rzeczywitych... Te generowane s¡ dopiero podczas uruchamiania programu przez program ªaduj¡cy.
Obecnie programuje si¦ w asemblerach coraz rzadziej (tendencja: programowanie staje si¦ coraz bardziej
specykowaniem tego co chcemy osi¡gn¡¢, a nie tego jak to chcemy osiagn¡¢).
Asemblery jednak mimo wszystko maj¡ zastosowania.
Programy asemblerowe maj¡ zazwyczaj krótszy
kod (wykonywalny) od tych pisanych w j¦zykach wysokiego poziomu i s¡ szybsze.
Wprawdzie je±eli chodzi
o du»e zadania, to kompilatory generuj¡ lepszy kod ni» ludzie, ale pewne drobne fragmenty czªowiek potra
zoptymalizowa¢ st¡d cz¦sto pisze si¦ program w j¦zyku wysokiego poziomu, po czym pewne kawaªki wstawia
si¦ w asemblerze.
Poza tym kto± musi pisa¢ kompilatory j¦zyków wysokiego poziomu tu znajomo±¢ asemblera jest konieczna...
2
Zarys architektury MIPS
Procesory rmy MIPS Technologies u»ywane s¡ w komputerach (Silicon Graphics), skomputeryzowanych zabawkach (Nintendo, Sony) oraz w systemach wbudowanych (w jakie wyposa»one s¡ np. telefony komórkowe).
Dwie podsawowe architektury: 32-bitowa (MIPS32) i 64-bitowa (MIPS64).
My zajmiemy si¦ 32-bitow¡ wersj¡ MIPSa wszystkie rejestry s¡ 32-bitowe, wszystkie rozkazy maj¡ dªugo±¢
32 bitów, przestrze« adresowa jest adresowana adresami 32-bitowymi, co pozwala zaadresowa¢ 4 GB.
Mimo, »e procesory MIPS s¡ typowymi architekturami RISC-owymi ich architektura zbioru rozkazów jest
w miar¦ bogata (RISC to mo»e nie tyle maªo rozkazów co proste rozkazy). Zawiera rozkazy arytmetyczne,
logiczne, porównuj¡ce, instrukcje przesyªu danych, rozgaª¦zienia, skoki. Jest architektur¡ typu ªaduj-zapisz,
co znaczy, »e wszystkie instrukcje (poza wczytywaniem danych i zapisywaniem) dziaªaj¡ na rejestrach (a nie
na komórkach pami¦ci gªónej).
MIPS32 ma 168 32-bitowych rozkazów, ale wiele z nich jest do siebie podobnych (jest np.
6 ró»nych
rozkazów dodawania). Posiada m.in. instrukcje NOP (nic nie rób, zajmuje tylko czas procesora, co czasem
mo»e by¢ sensowne). Mamy 32 rejstry ogólnego przeznaczenia: oznaczane od $0 do $31. Rejestr $0 ma na staªe
wpisan¡ warto±¢ 0, a rejestr $31 ($ra) jest domy±lny dla wielu rozkazów. Rejestr $1 ($at) jest zarezerwowany,
rejestry $27 ($k1)i $26 ($k0) u»ywane s¡ przez j¡dro systemu operacyjnego. Rejestry $28, $29, $30 ($gp, $sp,
$fp) s¡ rejestrami wska¹nikowymi. Numeracja pozostaªych rejestrów podana jest na rysunku 1. Ich znaczenie
zebrane jest tak»e poni»ej:
•
$at, $k0, $k1 - zarezerwowane dla asemblera i systemu operacyjnego (programista nie powinien ich
uzywac)
•
$a0-$a3 - przekazywanie argumentow do funkcji
•
$v0, $v1 - zwracanie wynikow przez funkcje
•
$t0-$t9 - rejestry pomocniecze
•
$s0-$s7 - rejestry danych
•
$gp - global pointer
•
$sp - stack pointer
1
•
$fp - frame pointer
•
$ra - return address ($31)
•
$0 - staªa zero
Warto podkre±li¢, »e podane zastosowania rejestrów s¡ tylko konwencj¡ i nic nie stoi na przeszkodzie, aby
wykorzystywa¢ je inaczej.
Rysunek 1: Konwencja nazewnictwa rejestrów MIPS32
Dodatkowo mamy dwa rejestry specjalne HI i LO przechowuj¡ce wyniki pewnych operacji na liczbach
caªkowitych.
Oczywi±cie jest te» licznik rozkazów PC. Inny zestaw 32 rejestrów to rejestry do operacji na
liczbach zmiennoprzecikowych. W trybie podwójnej precyzji warto±ci s¡ przechowywane w parach rejestrów o
kolejnych numerach. Jednostka zmiennoprzecikowa dysponuje te» 4 rejestrami specjalnego przeznaczenia.
Ze strony
http://www.cs.wisc.edu/ larus/spim.html
mo»na ±ci¡gn¡¢ emulator MIPS32, w wersjach
dla ró»nych systemów operacyjnych. Znajduje si¦ tam równie» sporo ciekawych linków.
3
Programowanie MIPSa
Jak wspomnieli±my wszystkie rozkazy (z wyj¡tkiem rozkazów przesyªania danych) operuj¡ tylko na rejestrach.
Konwencja: rejestry $s0-$s7 przechowuj¡ dane. Przykªad rozkazu:
add $s0, $s1, $s2
#
$s0=$s1+$s2
Grupa rejestrów $t0-$t7 przechowuje zgodnie z konwencj¡ zmienne tymczasowe.
s0 = (s1 + s2) − (s3 + s4)
Np. licz¡c wyra»enie:
napiszemy:
add $t0, $s1, $s2
add $t1, $s3, $s4
sub $s0, $t0, $t1.
Rozró»nienie mi¦dzy rejestrami $si i $ti jest umowne i nikt nie zabrania u»ywa¢ ich inaczej.
Operacja przesyªania z pami¦ci do rejestru to load word:
lw $s0,40($s1)
W powy»szym przykªadzie zawarto±¢ pami¦ci o adresie $s1+40 ªadowana jest do rejestru $s0.
»e mamy tu do czynienia z adresowaniem bazowym.
przeznaczenia.
Zauwa»my,
Jako bazy mo»emy u»y¢ dowolnego rejestru ogólnego
Przesuni¦cie jest podane jako argumnet natychmiastowy staªa (nie wolno w tym miejscu
u»y¢ rejestru).
W druga stron¦ mamy analogicznie dziaªaj¡c¡ operacj¦ store word:
sw $s0, 40($s1)
Uwaga o adresowaniu: pami¦¢ jest adresowana bajtowo, ale sªowo ma dªugo±¢ 4 bajtów, a wi¦c adres z
jakiego pobieramy lub do jakiego zapisujemy powinien by¢ wielokrotno±ci¡ 4. Staªa w rozkazach
pami¦tana na 16 bitach.
2
lw, sw
jest
3.1
Przykªad 1. Operacje na tablicy liczb caªkowitych
Adres pocz¡tku tablicy (czyli elementu
A[0])
przechowujemy w rejestrze $s0. Zaªadowanie elementu
A[12]
do
rejestru $s1 wygl¡da tak (pami¦tamy o tym, »e adresujemy bajtami):
lw $s1, 48($s0)
W jaki sposób odwoªa¢ si¦ do elementu tablicy, którego indeks jest przechowywany w rejestrze $s2 (typowa
sytuacja w programowaniu!)? Problem polega na tym, »e nie mamy adresowania po±redniego...
Rozwi¡zanie:
add
add
add
lw
3.2
$t0,
$t0,
$t0,
$s1,
$s2, $s2
$t0, $t0 # t0 = 4*i
$t0, $s0
0($t0)
# ªadujemy A[i] do s1
Formaty rozkazów MIPSa
Poznali±my ju» troch¦ instrukcji MIPS-a.
Podzieli¢ je mo»na na trzy rodzaje: typu I (immediate), typu R
(register) oraz typu J (jump). Jak te rozkazy wygl¡daj¡ w j¦zyku maszynowym?
•
Rozkazy typu R. Pierwszych 6 bitów to kod operacji (op).
Nast¦pnie mamy trzy razy po 5 bitów
wskazuj¡cych rejestry (rs, rt, rd), 5 bitów przesuni¦cia (shift ammount, shamt) oraz 6 bitów funkcji
(okre±laj¡ dodatkowe szczegóªy operacji). Np.
je dopiero bity funkcji.
add i sub maj¡ te same bity kodu operacji, rozrózniaj¡
add $t0, $s1, $s2 kolejne pola przyjmuj¡ warto±ci
W przypadku rozkazu
(dziesi¡tkowo): 0, 17, 18, 8, 0, 32.
Zauwa», »e rejestr przeznaczenia $t0 jest w kodzie maszynowym
zapisany jako trzeci, a nie jako pierwszy.
•
Rozkazy typu I. Np.
lw $s0, 8($t1).
Kod operacji zajmuje 6 bitów. Potem dwa razy po 5 bitów na
numery rejestrów i 16 bitów na adres (zapisany w kodzie dopeªnie« do 2).
Nasz rozkaz przykªadowy
zostanie zakodowany jako 35, 9, 16, 8. Inny przykªad rozkazu natychmiastowego:
Uwaga: nie ma
•
subi.
Rozkazy typu J. Np.:
j addr.
addi $s0, $s1, 3.
Kod operacji: 6 bitów. Adres: 26 bitów. Adres jest numerem sªowa a nie
bajtu i jest adresem wzgl¦dnym. Rzeczywisty adres do jakiego si¦ odwoªujemy: 4 najbardziej znacz¡ce
bity s¡ takie same jak w adresie rozkazu, nast¦pnie 26 bitów zakodowanych w adresie i na ko«cu 2 zera.
3.3
•
Kodowanie podstawowych konstrukcji z j¦zyków wysokiego poziomu
Konstrukcj¦:
if (i==j) s1=s2+s3 ;
if (i!=j) s1=s2-s3;
tªumaczymy na (przy zaªo»eniu, »e
bne
add
E1: beq
sub
E2:
i
jest w $s4, a j w $s5):
$s4 $s5 E1
$s1, $s2, $s3
$s4, $s5, E2
$s1, $s2, $s3
Uwaga: rozkazy skoku warunkowego:
bne, beq
s¡ typu I. Zatem adres ma w takim rozkazie ma tylko 16
bitów i mówi o ile trzeba skoczy¢ w stosunku do aktualnego miejsca w pami¦ci.
•
Konstrukcja
if (i==j) s1=s2+s3
else s1=s2+s3
tªumaczy si¦ na:
3
bne $s4, $s5 Else
add $s1, $s2, $s3
j EXIT
Else: sub $s1, $s2, $s3
Exit:
•
Nie ma rozkazu branch on less then. Do naturalnego przetªumaczenia konstrukcji
if (i<j)
s1=s2+s3
mo»na za to u»y¢ rozkazu set on less then:
DALEJ:
slt $t0, $s1, $s2 #set less than s1<s2 -> t0=1 else t0=0
beq $t0, $zero, DALEJ
add $s1, $s2, $s3
Innym rozwi¡zaniem jest u»ycie rozkazu
bgtz $i E (branch on greater than zero) lub bgez $i E (branch
on greater or equal zero).
•
P¦tla while:
while (s4 < s5)
s1=s2+s3
mo»e wygl¡da¢ tak:
Loop: slt $t0, $s4, $s5
beq $zero, $t0, EXIT
add $s1, $s2, $s3
j LOOP
EXIT:
3.4
Kompletny przykªad prostego programu
# Dodawanie elementow tablicy (przyklad zaczerpniety z
# ,,Krotkiego wprowadzenia do SPIM-a'' autorstwa Salah A. Almajdouba
.text
.align 2
.globl main
main:
loop:
STOR:
lw $s0, Size
li $s1, 0
li $s2, 0
li $t2, 4
mul $t1, $s1, $t2
lw $s3, Nstart($t1)
add $s2, $s2, $s3
addi $s1, $s1, 1
beq $s1, $s0, STOR
j loop
#
#
#
#
#
#
#
#
#
czyta rozmiar tablicy
indeks i
s2 bedzie przechowywac sume
t2 zawiera stala 4
t1 dostaje i * 4
s3 = N[i]
sum = sum + N[i]
i = i + 1
skaczemy do STOR na koniec
sw $s2, Result
# wynik zachowujemy w Result
.data
4
.align 2
Nstart: .word 8, 25, -5, 55, 33, 12, -78
Size:
.word 7
Result: .word 0
Uwagi:
1. dyrektywa
.text
oznacza, »e kolejne dane nale»y umieszcza¢ w segmencie programu
2. dyrektywa
.date
oznacza, »e kolejne dane nale»y umieszcza¢ w segmencie danych
3. dyrektwya
.align 2
4.
.word
5.
.globl
6.
li (load
nakazuje umieszcza¢ dane z wyrównaniem do
22
ka»e umieszcza¢ kolejne dane na 4 bajtach (jest te» dyrektywa
byte)
mówi, »e symbol jest globalny (widzialny z innych plików)
immediate nie jest rozkazem, a tzw. pseudorozkazem podczas tªumaczenia na kod maszynowy
przekªadane jest na ci¡g rozkazów (lub czasem pojedynczy rozkaz). Np.
ori s0,zero, 4.
li $s0, 4
przekªadane jest na
mul. Pseudorozkaz mul $s1, $s2, $s3 zostanie przeªo»ony na mult
mul umieszcza bardziej znacz¡c¡ cz¦±¢ wyniku w specjalnym rejestrze HI,
LO. Rozkaz mflo $s1 kopiuje zawarto±¢ LO do rejestru $s1.
7. Podobnie pseudorozkazem jest
$s2, $s3, mflo $s1.
Rozkaz
mniej znacz¡c¡ w rejestrze
8. konstrukcja
lw s3, N start(t1) rówznie» nie jest tutaj pojedynczym rozkazem maszynowy.
powodem jest
wyst¦pienie etykiety Nstart jako przesuni¦cia
9. podobnie jest z pierwszym rozkazem
28($1);
lw $0, Size,
który tªumacozny jest na:
lui $1, 4097, lw $16,
rejest $1 to rejestr $at
10. W tym przykªadzie u»yta jest nieco inna lozoa odwoªa« do pól tablicy ni» w przykªadzie wcze±niejszym:
staªa w odwoªaniu
lw $s3, Nstart($t1)
oznacza pocz¡tek tablicy, a rejstr przesuni¦cie.
Na kolejnym wykªadzie wróc¦ jeszcze na chwil¦ do pisania funkcji w asemblerze MIPS. Wtedy te» pojawi¡
sie jakie± notatki dotycz¡ce tego zagadnienia.
5