====== Architektury systemów komputerowych - Lista 9. ======
* {{:ask:09.lista09.pdf|Lista 9}}.
* [[http://cgi.aggregate.org/cgi-bin/cgispim.cgi|SPIM dostępny przez przeglądarkę]]
===== Zadanie 1. =====
Standard definiuje kilka formatow. Przyjmijmy http://en.wikipedia.org/wiki/Single_precision_floating-point_format .
Zakładamy, że $k >= 0$ (w zadaniu nie jest powiedziane, że mogą być ujemne)
main:
srl $s3, $s1, 23
andi $s3, $s3, 0xFF
add $s3, $s3, $s2
slti $t0, $s3, 0x100
bne $t0, $zero, nooverflow
nop ;tutaj powinien byc kod odpowiadajacy za wyjatek, czy cos tam
nooverflow:
sll $s3, $s3, 23
andi $t0, $s1, 0x807FFFFF
or $s3, $s3, $t0
===== Zadanie 2. =====
==== rozwiązanie 1 ====
FIXME Za to rozwiązanie poleciał duży grzybek
Program wypisze w kolejności 8, 4, 2 i 1 (więc jest big endian).
main:
addi $s0,$zero,0x0102
sll $s0,$s0,16
addi $s0,$s0,0x0408
li $v0, 1
andi $a0, $s0, 0xff
syscall
srl $s0, $s0, 8
andi $a0, $s0, 0xff
syscall
srl $s0, $s0, 8
andi $a0, $s0, 0xff
syscall
srl $s0, $s0, 8
andi $a0, $s0, 0xff
syscall
Program na pececie wypisze w kolejności 8, 4, 2 i 1 (a i386 jest little endian).
#include
#include
int main()
{
u_int32_t s0;
s0 = 0x0102;
s0 <<= 16;
s0 += 0x0408;
printf("%x\n", s0 & 0xff); s0 >>= 8;
printf("%x\n", s0 & 0xff); s0 >>= 8;
printf("%x\n", s0 & 0xff); s0 >>= 8;
printf("%x\n", s0 & 0xff); s0 >>= 8;
}
==== rozwiązanie 2 ====
.data
.asciiz "12345678901234567890"
tworzy
[0x10010000] 0x34333231 0x38373635 0x32313039 0x36353433
[0x10010010] 0x30393837 0x00000000 0x00000000 0x00000000
A więc stringi są little endian. Okazuje się, że prawdziwe MIPSy są bi-endian i można je ustawić na liltle i big.
==== rozwiązanie 3 ====
.data
dupa: .byte 0x01, 0x02
.text
main:
li $a2, 1
li $v0, 1
lw $a0, dupa($0)
syscall
===== Zadanie 3. =====
.data
buffer: .space 64
.text
main:
la $a0, buffer
li $a1, 64
li $v0, 8
syscall
la $t0, buffer
li $t2, 0x20
loop:
lb $t1, 0($t0)
beq $t1, $zero, exit
beq $t1, $t2, skip
xor $t1, $t1, $t2
sb $t1, 0($t0)
skip:
addi $t0, $t0, 1
j loop
exit:
li $v0, 4
la $a0, buffer
syscall
li $v0, 10
syscall
===== Zadanie 4. =====
main:
li $v0, 5
syscall
or $a0, $zero, $v0
jal fib
or $a0, $zero, $v0
li $v0, 1
syscall
li $v0, 10
syscall
fib:
addi $sp, $sp, -12
sw $ra, 4($sp)
sw $a0, 8($sp)
slti $t0, $a0, 2
beq $t0, $zero, L1
ori $v0, $zero, 1
j fib_ret
L1:
addi $a0, $a0, -1
jal fib
sw $v0, 0($sp)
addi $a0, $a0, -1
jal fib
lw $t0, 0($sp)
lw $ra, 4($sp)
lw $a0, 8($sp)
add $v0, $t0, $v0
fib_ret:
addi $sp, $sp, 12
jr $ra
===== Zadanie 5. =====
# newton(n,k) = 1, if k = 0 or k = n
# newton(n,k) = newton(n-1,k-1) + newton(n-1,k) otherwise
main:
li $v0, 5
syscall
or $a0, $zero, $v0 #get n
li $v0, 5
syscall
or $a1, $zero, $v0 #get k
jal newton
or $a0, $zero, $v0
li $v0, 1
syscall #print returned value
li $v0, 10
syscall #exit
newton:
addi $sp, $sp, -8
sw $ra, 0($sp)
beq $a0, $a1, L1
beq $a1, $zero, L1
addi $a0, $a0, -1
jal newton
sw $v0, 4($sp)
addi $a1, $a1, -1
jal newton
addi $a0, $a0, 1
addi $a1, $a1, 1
lw $t0, 4($sp)
lw $ra, 0($sp)
add $v0, $t0, $v0
j newton_ret
L1:
ori $v0, $zero, 1
newton_ret:
addi $sp, $sp, 8
jr $ra
===== Zadanie 6. =====
# a0 - a, a1 - n, a2 - x
# v0 - res, t0 - i
count:
ori $v0, $zero, 0
ori $t0, $zero, 0
for:
beq $t0, $a1, endfor
sll $t1, $t0, 2
add $t1, $a0, $t1 # $t1 = a+i
lw $t2, 0($t1)
bne $t2, $a2, continue
addi $v0, $v0, 1
continue:
addi $t0, $t0, 1
j for
endfor:
int count (int *a, int n, int x)
{
int *p, res = 0;
for (p=a; p!=a+n; p++)
if (*p == x)
res++;
return res;
}
count:
ori $v0, $zero, 0
ori $t0, $a0, 0
sll $t1, $a1, 2
add $t1, $a0, $t1
for:
beq $t0, $t1, endfor
lw $t2, 0($t0)
bne $t2, $a2, continue
addi $v0, $v0, 1
continue:
addi $t0, $t0, 4
j for
endfor:
===== Zadanie 7. =====