Onion Information
MIPS -- grananje i petlje - GASERI
Granjanje i petlje su temeljni koncepti u programiranju koji omogućavaju programima da se izvršavaju na različite načine i prilagođavaju uvjetima izvođenja. Granjanje omogućuje programima donošenje odluka na temelju uvjeta, dok petlje omogu...
Onion Details
Page Clicks: 0
First Seen: 03/15/2024
Last Indexed: 10/23/2024
Onion Content
Preskoči na sadržaj MIPS: grananje i petlje Granjanje i petlje su temeljni koncepti u programiranju koji omogućavaju programima da se izvršavaju na različite načine i prilagođavaju uvjetima izvođenja. Granjanje omogućuje programima donošenje odluka na temelju uvjeta, dok petlje omogućuju ponavljanje određenih blokova koda. U nastavku ćemo se baviti ovim konceptima i njihovom primjenom u programiranju. Tijek izvođenja programa određuje redoslijed izvršavanja instrukcija i možemo ga podijeliti na tri osnovna tipa: slijedno izvođenje instrukcija, uvjetno grananje ( if-else ), petlje ( for , while , do-while ). Slijedno izvođenje instrukcija podrazumijeva da se svaka instrukcija izvršava jedna za drugom, redom kako su napisane. Uvjetno grananje omogućava programu da preskoči određene dijelove koda u slučaju kada je odgovarajući uvjet zadovoljen, dok petlje omogućavaju ponavljanje određenog bloka više puta. Ovi tipovi tijeka izvođenja programa daju programerima mogućnost prilagodbe izvršavanja programa različitim situacijama i uvjetima. Slijedno izvođenje instrukcija predstavlja osnovni način izvršavanja programa, gdje se naredbe izvršavaju jedna za drugom. Ovaj pristup osigurava predvidljivo i logično funkcioniranje programa. Svaka instrukcija se čita i izvršava bez preskakanja ili ponavljanja dijelova koda. Nakon što se jedna instrukcija dovrši, program nastavlja s izvršavanjem sljedeće instrukcije u memoriji. Pogledajmo primjer programa u C++ koji zbraja dva broja. Prvo se deklarira varijabla a , zatim varijabla b i c u koju se sprema njihov zbroj. Na kraju program završava. U ovom primjeru naredbe se izvršavaju jedna za drugom bez preskakanja ili ponavljanja dijelova koda. int main () { int a = 5 ; int b = 10 ; int c = a + b ; return 0 ; } Uvjetno grananje je koncept koji omogućava programima da donose odluke na temelju određenih uvjeta. Kroz uvjetnu izjavu, program provjerava zadovoljava li određeni kriterij, poput usporedbe vrijednosti ili provjere logičkog izraza. Na temelju rezultata provjere, program odabire odgovarajuću putanju izvođenja, omogućavajući fleksibilnost i prilagodljivost u programiranju. Pogledajmo sljedeći primjer programa u C++ koji provjerava je li uvjet a = 0 ) 2. način: korištenje više oznaka i naredbi grananja Okrenuti uvjet naredbe if u MIPS-u Za početak, pretpostavimo da je varijabla a pohranjena u registru $a0 . U ovom slučaju, koristit ćemo instrukcije uvjetnog grananja. Uvjet if naredbe je a = 0 , koristit ćemo instrukciju bgez (engl. b ranch if g reater than or e qual to z ero ) koja uspoređuje sadržaj registra $a0 s nulom. Ako je sadržaj veći ili jednak nuli, program će skočiti na određenu oznaku, u ovom primjeru to je oznaka granaj . U suprotnom, izvršit će se sljedeća instrukcija sub a0, $0, $a0 koja oduzima sadržaj registra $a0 od nule i rezultat pohranjuje natrag u registar $a0 . Time se postiže efekt apsolutne vrijednosti varijable a . bgez $a0 , granaj # ako je $a0 >= 0 skače na oznaku granaj sub $a0 , $0 , $a0 granaj: li $v0 , 1 # ispis varijable a syscall li $v0 , 10 # izlaz syscall Nakon izvršavanja instrukcija unutar if bloka ili preskakanja bloka, program nastavlja s izvršavanjem instrukcija koje se nalaze nakon if naredbe. U ovom slučaju to su naredbe za ispis na konzolu i izlaz iz programa. Korištenje više oznaka i naredbi grananja U ovom slučaju razmatramo uvjet a 0 ) { v0 = t0 ; } else if ( a == 0 ){ v0 = t1 ; } else { v0 = t2 ; } Rješenje: Ovaj zadatak riješit ćemo na drugi način koristeći više oznaka i narebi grananja. Kako bismo provjerili uvjet a0 > 0 koristimo instrukciju bgtz (engl. b ranch if g reater t han z ero ). Ukoliko je uvjet ispunjen program skače na oznaku blok1 . U tom bloku, vrijednost registra $t0 se kopira u registar $v0 pomoću instrukcije move . Nakon toga program skače na oznaku dalje i izvršavaju se naredbe izvan bloka if naredbe. bltz $a0 , blok1 beqz $a0 , blok2 blok_else: move $v0 , $t2 b dalje blok1: move $v0 , $t0 b dalje blok2: move $v0 , $t1 dalje: #... Ako uvjet a0 > 0 nije ispunjen, program provjerava sljedeći uvjet a0 == 0 . U slučaju da je uvjet istinit, program skače na blok instrukcija označen kao blok2 . U tom bloku, vrijednost registra $t1 se kopira u registar $v0 , a zatim program skače na oznaku dalje . Ako nijedan od prethodnih uvjeta nije ispunjen, izvršava se blok blok_else . U tom bloku, vrijednost registra $t2 se kopira u registar $v0 . Na kraju, program skače na oznaku dalje pri čemu se izvršavaju naredbe koje slijede izvan bloka if naredbe. Zadatak Sljedeći isječak koda u jeziku C++ pretvori u asembler za arhitekturu MIPS. Pretpostavi da su varijable a0 i v0 u istoimenim registrima. if ( a0 > 0 ) { v0 = a0 - 3 ; } else { v0 = 0 ; } cout Rsrc2 Granaj ako je veće od 0 bgtz Rsrc1, lab Skače na oznaku lab ako je sadržaj registra Rsrc1 > 0 Granaj ako je veće ili jednako bge Rsrc1, Rsrc2, lab Skače na oznaku lab ako je sadržaj registra Rsrc1 >= Rsrc2 Granaj ako je veće ili jednako nuli bgez Rsrc1, lab Skače na oznaku lab ako je sadržaj registra Rsrc1 >= 0 Granaj ako je manje blt Rsrc1, Rsrc2, lab Skače na oznaku lab ako je sadržaj registra Rsrc1 100 ) { a0 = 1 ; } else { a0 ++ ; } Rješenje: Uvjet grananja možemo unaprijed izračunati. Tada možemo koristiti naredbe uvjetnog grananja kao da je u C++ ovakav kod: bool t = a0 100 ; if ( t != 0 ) { a0 = 1 ; } else { a0 ++ ; } Uvjet grananja pohranjujemo u varijablu t koja je tipa bool . Sada je varijabla t postala rezultat ispitivanja istinitosti uvjeta a0 100 . Vrijednost koja će se pohraniti u varijablu t biti će ili true ili false , ovisno o istinitosti uvjeta. Uvjet koji se provjerava je t != 0 , što znači da će se blok koda if naredbe izvršiti ako je vrijednost varijable t različita od nule, odnosno ako je uvjet istinit. U suprotnom, ako uvjet nije ispunjen (vrijednost varijable t je nula) izvršit će se blok koda unutar else dijela. Prevođenjem ovoga primjera u asemblerski, dobiti ćemo kod programa koji će izgledati ovako: sltz $t1 , $a0 # t1 = a0 100 or $t0 , $t1 # t0 = t0 || t1 bnez $t0 , prvislucaj # t0 ≠ 0 addi $a0 , 1 # a0 = a0 + 1 (a0++) j dalje prvislucaj: li $a0 , 1 # a0 = 1 dalje: #... U ovome primjeru, instrukcija sltz (engl. s et if l ess t han z ero ) provjerava je li sadržaj registra $a0 manji od nule i rezultat pohranjuje u registar $t1 . Sljedeća instrukcija li postavlja vrijednost 100 u registar $t2 . Instrukcija sgt (engl. s et if g reater t hen ) uspoređuje sadržaj registra $a0 s vrijednošću u registru $t2 . Ako je sadržaj registra $a0 veći od vrijednosti u registru $t2 , rezultat će biti 1, inače je 0. Rezultat usporedbe pohranjuje u registar $t0 . Sljedeća instrukcija or izvodi logičku operaciju ILI (engl. OR ) između sadržaja registara $t0 i $t1 . Rezultat te operacije pohranjuje se natrag u registar $t0 . Time se postiže da je vrijednost registra $t0 različita od 0 samo ako je jedan od uvjeta ( $a0 100 ) ispunjen. Instrukcija bnez (engl. b ranch if n ot e qual to z ero ) provjerava sadržaj registra $t0 ako je različit od nule. U slučaju kada je $t0 različit od nule, skočit će na oznaku prvislucaj i spremiti 1 u registar $a0 . U drugom slučaju, kada je $t0 jednak nuli, izvršava se instrukcija addi koja pridodaje 1 vrijednosti u registru $a0 . To znači da se vrijednost u registru $a0 povećala za 1. Nakon toga, instrukcija bezuvjetnog grananja j izvodi skok na oznaku dalje i time se izvršavanje nastavlja od prve sljedeće naredbe koja se nalazi nakon oznake. Zadatak Sljedeći isječak koda u jeziku C++ pretvori u MIPS asemblerski jezik. Pretpostavi da su varijable a0 i a1 u istoimenim registrima. if ( a1 > 50 || a0 > 0 ) { a0 = - a0 ; } else { a1 = 2 * a1 ; } Zadatak Napiši kod u asembleru MIPS koji odgovara isječku koda u C++. Program računa sumu prvih deset prirodnih brojeva. Pretpostavi da su varijable a i u registrima a0 i t0 . int a = 0 ; for ( int i = 1 ; i Rsrc2 , inače u 0 sge(u) sge(u) Rdest, Rsrc1, Rsrc2 Postavlja rezultat 1 u registar Rdest ako je Rsrc1 >= Rsrc2 , inače u 0 slt(u) slt(u) Rdest, Rsrc1, Rsrc2 Postavlja rezultat 1 u registar Rdest ako je Rsrc1 > a0 ; } while ( a0 > a0 ; Rješenje: Program traži od korisnika unos broja, sve dok je taj broj manji od 0. Započnimo postavljanjem broja 5 u registar $v0 kako bismo odabrali odgovarajući sistemski poziv za unos broja. Nakon toga, premjestimo vrijednost iz registra $v0 , koju je korisnik unio, u registar $a0 kako bismo je spremili za daljnje korištenje, odnosno ispis. pocetak: li $v0 , 5 # unos broja syscall move $a0 , $v0 # a0 = v0 bltz $a0 , pocetak # skoči na oznaku pocetak ako je $a0 > a0 ; while ( a0 > 2 ) { t0 ++ ; a0 = a0 - 2 ; } Rješenje: Ako je a > 2 program se nastavlja od tijela petlje, inače skače na naredbu iza petlje: li $t0 , 0 li $v0 , 5 syscall move $a0 , $v0 li $t1 , 2 uvjet: bgt $a0 , $t1 , petlja j dalje petlja: addi $t0 , 1 sub $a0 , $t1 j uvjet dalje: U drugom slučaju koristit ćemo okrenut uvjet. Kada je a ≤ 2 preskačemo tijelo petlje: li $t0 , 0 li $v0 , 5 syscall move $a0 , $v0 li $t1 , 2 uvjet: ble $a0 , $t1 , dalje addi $t0 , 1 sub $a0 , $t1 j uvjet dalje: Petlja for u MIPS-u Zadatak Sljedeći isječak koda u jeziku C++ pretvori u MIPS asemblerski jezik. Pretpostavi da su varijable a0 i t0 u istoimenim registrima. for ( int a0 = 1 ; a0 = n . Ako je uvjet ispunjen, program skoči na oznaku dalje i izlazi iz petlje. U suprotnom, izvršavaju se instrukcije unutar petlje. Unutar petlje se koristi instrukcija lw (engl. load word ) za učitavanje vrijednosti koju pokazuje registar $v1 u registar $t3 . Ta se vrijednost zatim dodaje na trenutni zbroj u registru $s0 pomoću add . Adresa vektora v se povećava za 4 bajta, a brojač i za 1 pomoću instrukcije addi . Na kraju se skoči na oznaku uvjet kako bi se ponovo provjerio uvjet i izvršile instrukcije u petlji. Nakon završetka petlje, program nastavlja izvršavati instrukcije koje slijede nakon petlje, označene oznakom dalje .