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) 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) Np. licz c wyra»enie: W powy»szym przykªadzie zawarto± pami ci o adresie $s1+40 ªadowana jest do rejestru $s0. Zauwa»my,»e mamy tu do czynienia z adresowaniem bazowym. Jako bazy mo»emy u»y dowolnego rejestru ogólnego przeznaczenia. 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 lw, sw jest pami tana na 16 bitach. 2
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 $t0, $s2, $s2 add $t0, $t0, $t0 # t0 = 4*i add $t0, $t0, $s0 lw $s1, 0($t0) # ªadujemy A[i] do s1 3.2 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. add i sub maj te same bity kodu operacji, rozrózniaj je dopiero bity funkcji. W przypadku rozkazu add $t0, $s1, $s2 kolejne pola przyjmuj warto±ci (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: addi $s0, $s1, 3. Uwaga: nie ma subi. Rozkazy typu J. Np.: j addr. 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 i jest w $s4, a j w $s5): bne $s4 $s5 E1 E1: beq $s4, $s5, E2 sub $s1, $s2, $s3 E2: 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 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: slt $t0, $s1, $s2 #set less than s1<s2 -> t0=1 else t0=0 beq $t0, $zero, DALEJ DALEJ: 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 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 main:.text.align 2.globl main lw $s0, Size # czyta rozmiar tablicy li $s1, 0 # indeks i li $s2, 0 # s2 bedzie przechowywac sume li $t2, 4 # t2 zawiera stala 4 loop: mul $t1, $s1, $t2 # t1 dostaje i * 4 lw $s3, Nstart($t1) # s3 = N[i] add $s2, $s2, $s3 # sum = sum + N[i] addi $s1, $s1, 1 # i = i + 1 beq $s1, $s0, STOR # skaczemy do STOR na koniec j loop STOR: 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 nakazuje umieszcza dane z wyrównaniem do 2 2 4..word ka»e umieszcza kolejne dane na 4 bajtach (jest te» dyrektywa byte) 5..globl mówi,»e symbol jest globalny (widzialny z innych plików) 6. li (load 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. li $s0, 4 przekªadane jest na ori s0,zero, 4. 7. Podobnie pseudorozkazem jest mul. Pseudorozkaz mul $s1, $s2, $s3 zostanie przeªo»ony na mult $s2, $s3, mflo $s1. Rozkaz mul umieszcza bardziej znacz c cz ± wyniku w specjalnym rejestrze HI, mniej znacz c w rejestrze LO. Rozkaz mflo $s1 kopiuje zawarto± LO do rejestru $s1. 8. konstrukcja lw s3, Nstart(t1) rówznie» nie jest tutaj pojedynczym rozkazem maszynowy. powodem jest wyst pienie etykiety Nstart jako przesuni cia 9. podobnie jest z pierwszym rozkazem lw $0, Size, który tªumacozny jest na: lui $1, 4097, lw $16, 28($1); 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