You are on page 1of 6

Архитектура и организација на компјутери

Лабораториска вежба 4 - МИПС

Презиме, име и индекс _____________________________________________________

Примери со инструкции за разгранување


C Mips

Пример 1: Читаме цел број и пресметуваме негова апсолутна вредност

#include <stdio.h> .data


int main() { .text
int z; li $v0, 5
scanf("%d", &z); syscall

add $t0, $v0, $zero


//apsolutna vrednost
if (z < 0) { slt $t1, $t0, $zero
beq $t1, $zero, nadvor_od_if

if_pocetok:
z = -z;
sub $t0, $zero, $t0
}
nadvor_od_if:
add $a0, $t0, $zero
li $v0, 1
printf("%d", z);
syscall

li $v0, 10
return 0; syscall
}

Пример 2: Се чита целобројна вредност од тастатура. Доколку внесениот бројот е позитивен,


тогаш се множи со 3, инаку се множи со -3. Вака добиената вредност се печати на екран.

#include <stdio.h> .data


int main() { .text
int z; li $v0, 5
scanf("%d", &z); syscall # прочитај цел број од тастатура
add $t0, $v0, $zero
slt $t1, $t0, $zero # проверка (t1=1 ако t0 < 0, t1=0
ако е t0 >= 0)
if (z < 0) {

#сега, гледаме дали важи обратното од ИФ а тоа е >= и


скокаме кон else
beq $t1, $zero, else_pocetok
If_pocetok:
li $t1,-3
mul $t0, $t1
mflo $a0
z = z * -3; j kraj # безусловен скок
} else_pocetok:
else { li $t1,3
z = z * 3; mul $t0, $t1
} mflo $a0
kraj:
li $v0, 1
syscall #печати на екран
printf("%d", z); li $v0, 10
syscall #крај на програмата
return 0;
}

Пример 3: Читаме низа од знаци. Со циклус го изминуваме секој знак додека не стигнеме до
крајот, т.е. до ‘\0’. Секој знак го зголемуваме за 3 и го запишуваме назад. Печатиме.

#include <stdio.h> .data


char * t[31]; t: .space 31 #резервираме 31 бајт во овој сегмент (+0
до +30)
#гледаме дека b почнува на 33-тиот бајт (+32). зошто?
порамнување.
b: .word 1234567
int b = 1234567;
.text
int main() { #читаме низа од знаци, макс 30 знаци и еден бајт е за
'\0'
la $a0, t
char * t0 = t;
li $a1, 31
li $v0, 8
fgets(t, 31, stdin); syscall

la $t0, t

ciklus:
lbu $t1, 0($t0)
beq $t1, $zero, ciklus_kraj #ako e = ’\0’ izlezi
while(*t0 != '\0') {
addiu $t1, $t1, 3
sb $t1, 0($t0)
*t0 += 3;
addi $t0, $t0, 1
j ciklus
t0++;
} ciklus_kraj:

#la $a0, t
li $v0, 4
syscall

li $v0, 10
fputs(t, stdout); syscall

return 0;
}
Задачи
Задача 1: Разгледајте ги примерите и извршете ги чекор по чекор.

Задача 2: Внесете број од тастатура. Ако бројот се наоѓа во интервалот [-5, 105) или е
поголем од 105050 или пак е помал или еднаков со -70999, тогаш на екран напишете
„во интервал“. Во спротивно, напишете „надвор од интервал“.
.data
interval: .asciiz “vo interval”
nadvor: .asciiz “nadvor od interval”
.text
li $v0,5
syscall
#procitaj broj
add $t0, $v0, $zero #t0 e procitaniot broj
slti $t1, $t0, -5 #1 ako $t0<-5, 0 ako e >=-5
addi $s0, $zero, 1 #$s0=1
beq $t1, $s0, proverka1
slti $t1, $t0, 105 #1 ako $t0<105, 0 ako e >=105
beq $t1, $s0, pecati
li $t1, 105050
slt $t1, $t1, $t0 #1 ako 105050<t0, 0 ako >=t0
beq $t1, $s0, pecati
beq $t1, $zero, inaku
proverka1:
li $t1, -70999
slt $t2, $t1, $t0 #1 ako -70999<$t0, 0 ako e >=t0
beq $t2, $zero, pecati
beq $t2, $s0, inaku
pecati:
la $a0, interval
li $v0, 4
syscall
j kraj
inaku:
la $a0, nadvor
li $v0, 4
syscall
kraj:
li $v0, 10
syscall

Забелешки:
-Операциите помало, поголемо, помало или еднакво и поголемо или еднакво потребно
е да ги испрограмирате со помош на инструкциите, slt, slti, beq и bne
-Некои од константите зафаќаат повеќе од 16 бита.
Задача 3: Да се напише програма која чита два броја b1 и b2 (b1 < b2) и ја печати на
екран сумата на сите броеви во опсегот од b1 до b2 кои при делење со бројот 4 имаат
остаток 1.
.text
li $v0, 5
syscall
add $t0, $v0, $zero
li $v0, 5
syscall
add $t1, $v0, $zero
li $s0, 0
beq $t0, $t1, kraj
addi $s1, $zero, 1
ciklus:
beq $t0, $t1, kraj
addi $t2, $zero, 4
div $t0, $t2
mfhi $t3
beq $t3, $s1, dodadi
addi $t0, $t0, 1
j ciklus
dodadi:
add $s0, $s0, $t0
add $t0, $t0, 1
j ciklus
kraj:
add $a0, $s0, $zero
li $v0, 1
syscall
li $v0, 10
syscall

Задача 4: Да се напише процедура во MIPS која за даден влезен аргумент од тип


string ќе ја најде неговата должина и ќе ја испечати. Потоа, напишете главна програма
во која ќе ја тестирате процедурата така што два пати едно по друго ќе ја повторите
постапката: внесување на низа од тастатура, повикување на процедурата и печатење
на должината на низата на екран.
.data
Niza1: .space 50
Niza2: .space 50
.text
la $a0, Niza1
li $a1, 50
li $v0, 8
syscall
jal procedure
addi $a0, $v0, 0
li $v0, 1
syscall
la $a0, Niza2
li $a1, 50
li $v0, 8
syscall
jal procedure
addi $a0, $v0, 0
li $v0, 1
syscall
li $v0, 10
syscall
procedure:
add $s0, $zero, $zero
add $t0, $a0, $zero
loop:
lbu $t1, 0($t0)
beq $t1, $zero, kraj
addi $t0, $t0, 1
addi $s0, $s0, 1
j loop
kraj:
addi $s0, $s0, -1
addi $v0, $s0, 0
jr $ra

Забелешка: искористете го пример 3.

Која е содржината на регистарот $pc пред и по повикувањето на процедурата во двата


случаи?

Која е содржината на регистарот $ra пред и по повикувањето на процедурата во двата


случаи?
Која е содржината на регистарот $pc пред и по извршувањето на последната
инструкција од процедурата и во двата случаи?

Кој е заклучокот за употребата на ресгистарот $ra и инструкциите jal и jr при


имплементација на процедури?

You might also like