====== 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. =====