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