soluzione
Transcript
soluzione
COMPITINO #1 di CALCOLATORI ELETTRONICI 1 del 22-02-05 MATRICOLA__________________ COGNOME____________________ NOME____________________ 1) Trovare il codice assembly MIPS corrispondente al seguente programma (utilizzando solo e unicamente istruzioni dalla tabella sottostante), rispettando le convenzioni di utilizzazione dei registri dell’assembly MIPS (riportate in calce, per riferimento). char buff[80] = “Britney Spears\n”; char to_upper(char c) { if (c >= ‘a’ && c <= ‘z’) c -= 0x20; return (c); } char *myfun(int n, char *p, char c, float f, double d) { char *r, *s = p; while (*s++ != ‘\0’ && n-- > 0) { *s = to_upper(*s); if (*s == c) r = s; } if (f * d < 0) { f = -f; r = myfun(7, r, c, f, d); } return (r); } main() { char *p; printf(buff); p = myfun(7, buff, ‘E’, 1, -1); printf(p); } MIPS instructions Instruction add subtract add immediate subtract immediate multiplication division move from Hi move from Lo and or nor xor and immediate or immediate xor immediate shift left logical shift right logical load word load byte load byte unsigned store word store byte load address branch on equal branch on not equal set on less than set on less than immediate set on less than unsigned set on less than imm. unsigned jump jump register jump and link add.s add.d sub.s sub.d mul.s mul.d div.s div.d mov.s mov.d abs.s abs.d c.lt.s c.lt.d (eq,ne,le,gt,ge) branch on false branch on true load floating point (32bit) store floating point (32bit) convert single into double convert single into integer Register Usage Name Register Num. $zero 0 $s0-$s7 16-23 $t0-$t9 8-15,24-25 $a0-$a3 4-7 Example add $1,$2,$3 sub $1,$2,$3 addi $1,$2,100 subi $1,$2,100 mult $1, $2 div $1, $2 mfhi $1 mflo $1 and $1,$2,$3 or $1,$2,$3 nor $1,$2,$3 xor $1,$2,$3 andi $1,$2,100 ori $1,$2,100 xori $1,$2,100 sll $1,$2,10 srl $1,$2,10 lw $1,100($2) lb $1,100($2) lbu $1,100($2) sw $1,100($2) sb $1,100($2) la $1,var beq $1,$2,100 bne $1,$2,100 slt $1,$2,$3 slti $1,$2,100 sltu $1,$2,$3 sltiu $1,$2,100 j 10000 jr $31 jal 10000 add.x $f0,f2,$f4 add.x $f0,f2,$f4 mul.x $f0,f2,$f4 div.x $f0,f2,$f4 mov.x $f0,$f2 abs.x $f0,$f2 c.lt.x $f0,$f2 bc1f label bc1t label lwc1 $f0,0($1) swc1 $f0,0($1) cvt.d.s $f0,$f2 cvt.w.s $t0,$f0 Usage The constant value 0 Saved Temporaries Arguments Name $v0-$v1 $fp, $sp $ra, $gp $k0-$k1 Meaning $1 = $2 + $3 $1 = $2 - $3 $1 = $2 + 100 $1 = $2 - 100 Hi,Lo= $1 x $2 Hi= $1 % $2, Lo = $1 / $2 $1 = Hi $1 = Lo $1 = $2 & $3 $1 = $2 | $3 $1 = !($2 | $3) $1 = $2 ^ $3 $1 = $2 & 100 $1 = $2 | 100 $1 = $2 ^ 100 $1 = $2 << 10 $1 = $2 >> 10 $1 = Memory[$2+100] $1 = Memory[$2+100] $1 = Memory[$2+100] Memory[$2+100] = $1 Memory[$2+100] = $1 $1 = &var if ($1 = = $2) go to PC+4+100 if ($1 != $2) go to PC+4+100 if ($2 < $3) $1 = 1; else $1 = 0 if ($2 < 100) $1 = 1; else $1 = 0 if ($2 < $3) $1 = 1; else $1 = 0 if ($2 < 100) $1 = 1; else $1 = 0 go to 10000 go to $31 $31 = PC + 4;go to 10000 $f0=$f2+$f4 $f0=$f2-$f4 $f0=$f2*$f4 $f0=$f2/$f4 $f0Å$f2 $f0=ABS($f2) Temp=($f0<$f2) If (Temp = = false) go to label If (Temp = = true) go to label $f0ÅMemory[$1] Memory[$1]Å$f0 $f0=(double)$f2 $t0=(int)$f0 Register Num. 2-3 30,29 31,28 26,27 Usage Results Frame pointer, stack pointer return address, global pointer Kernel usage Comments 3 operands; exception possible 3 operands; exception possible + constant; exception possible - constant; exception possible 64-bit Signed Product ; result in Hi,Lo Signed division Create copy of Hi Create copy of Lo 3 register operands; Logical AND 3 register operands; Logical OR 3 register operands; Logical NOR 3 register operands; Logical XOR Logical AND register, constant Logical OR register, constant Logical XOR register, constant Shift left by constant Shift right by constant Data from memory to register Data from memory to register Data from mem. to reg.; no sign extension Data from register to memory Data from register to memory Load variable address Equal test; PC relative branch Not equal test; PC relative Compare less than; 2`s complement Compare < constant; 2`s complement Compare less than; natural number Compare constant; natural number Jump to target address For switch, procedure return For procedure call Single and double precision add Single and double precision subtraction Single and double precision multiplication Single and double precision division Single and double precision move Single and double precision absolute value Single and double: compare $f0 and $f2 <,=,!=,<=,>,>= Temp is ‘Condition-Code’ Temp is ‘Condition-Code’ Also cvt.s.d (viceversa) Also cvt.s.w (viceversa) Name $f0, $f1, …, $f31 $f0, $f2, …, $f30 Usage Single precision floating point registers Double precision floating point registers COMPITINO #1 di CALCOLATORI ELETTRONICI 1 del 22-02-05 Si presenta una possible soluzione: .data buff: .asciiz "Britney Spears\n" .space 64 zerof: .float 0.0 punof: .float 1.0 munod: .double -1.0 tempf: .float 0.0 .text .globl main to_upper: slti $t0, bne $t0, addi $t1, slt $t2, bne $t0, addi $a0, ret_to_upper: add $v0, jr $ra myfun: addi sw add sw sw sw sw sw sw sw $a0, 'a' $0, ret_to_upper $0, 'z' $t1, $a0 $0, ret_to_upper $a0, -0x20 $a0, $0 $sp, $sp, -32 # 8 per var.locali, 4 per $ra, 4 $fp, 16 arg. $fp, 12($sp) $fp, $sp, $0 # inizializza il nuovo frame pointer # d -->inserito dal chiamante $a3, 28($fp) # f $a2, 24($fp) # c $a1, 20($fp) # p $a0, 16($fp) # n $ra, 8($fp) # ind. ritorno $s1, 4($fp) # $s1 = s $s0, 0($fp) # $s0 = r add $s1, while_start: lb $t0, addi $s1, beq $t0, add $t1, addi $a0, slt $t2, beq $t2, $a1, $0 # s = p 0($s1) # *s $s1, 1 # s++ $0, while_end # salta se la prima cond. e' falsa $a0, $0 # n $a0, -1 # n-$0, $t1 # 0 <? n $0, while_end # salta se la seconda cond. e' falsa sw lb add jal lw sb lb bne $a0, 16($fp) # save $a0, richiesto da to_upper $t0, 0($s1) # nuovo *s $a0, $t0, $0 # setup del parametro di input to_upper # chiama to_upper $a0, 16($fp) # ripristina $a0 $v0, 0($s1) # memorizza resultato, *s = ... $t0, 0($s1) # nuovo *s $t0, $a2, while_start add j $s0, $s1, $0 while_start while_end: lwc1 $f0, 28($fp) lwc1 $f2, 32($fp) lwc1 $f3, 36($fp) cvt.d.s $f4, $f0 la $t0, zerof # r = s # # # # carica f in $f0 carica d in ($f2,$f3) 64 bit... converti f in double SOLUZIONE COMPITINO #1 di CALCOLATORI ELETTRONICI 1 del 22-02-05 lwc1 $f30, 0($t0) cvt.d.s $f8, $f30 SOLUZIONE # ($f8,$f9) = 0.0 (double) mul.d $f6, $f2, $f4 # (double)f * d c.lt.d $f6, $f8 # f*d <? 0 bc1f if_end sub.s $f12, $f30, $f12 # f = -f addi $a0, $0, 7 # $a0 = 7 add $a1, $s0, $0 # $a1 = r # $a2 e' a posto = c la $t0, tempf # espediente per non usare swc1 $f12, 0($t0) # la mfc1 $a3, $f12 lw $a3, 0($t0) # cosi' sistemo $a3 addi swc1 swc1 $sp, $sp, -8 $f2, 0($sp) $f3, 4($sp) jal myfun add $s0, $v0, $0 # r = risultato di myfun if_end: add $v0, $s0, $0 # parametro restituito $a0, $a1, $a2, $a3, $ra, $fp, $sp, $ra # # # # # # # lw lw lw lw lw lw addi jr 16($fp) 20($fp) 24($fp) 28($fp) 8($fp) 12($fp) $sp, 40 main: la $a0, buff addi $v0, $0, 4 syscall addi la addi la lw addi la lw sw lw sw $a0, $a1, $a2, $t0, $a3, $sp, $t0, $t1, $t1, $t2, $t2, $0, 7 buff $0, 'E' punof 0($t0) $sp, -8 munod 0($t0) 0($sp) 4($t0) 4($sp) jal myfun add $a0, $v0, $0 addi $v0, $0, 4 syscall addi $v0, $0, 10 syscall # quinto parametro = d ripristina a0, a1, a2, a3 (necessario a causa della chiamata ricorsiva) ripristina $ra, $fp (necessario a causa della chiamata ricorsiva) ripristina lo stack e butta i parametri locali r e s