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