Download as pdf or txt
Download as pdf or txt
You are on page 1of 11

Computer Organization

Sheet 2_Part 4
Supporting Procedures (cont.)
Register number Preserve on
Name Usage
(decimal) call?
$zero 0 the constant value 0 n.a.
$at 1 reserved for the assembler n.a.
procedure return values and
$v0-$v1 2-3 no
expression evaluation
$a0-$a3 4-7 Caller (parameters)
procedure arguments Callee no
$t0-$t7 8-15 function
temporary registers function no
$s0-$s7 16-23 Saved/purpose
general saved registers
($t0-$t9) yes
Restored ($s0-$s7)
$t8-$t9 24-25 more temporary ($a0-$a3)
registers $gp,$fp, $sp, $ra no
registers ($v0,
$k0-$k1 26-27 reserved for the OS$v1) n.a.
$gp 28 global pointer yes
$sp 29 stack pointer yes
$fp 30 frame pointer yes
$ra 31 procedure return address yes
Q16: Consider the following C-language program. Functions main(), calculate(), evaluate(), and square() are
placed starting at locations 60010, 70010, 80010, and 90010, respectively in memory. Integer variables c, d, and i are
stored in registers $s0, $s1, and $s2, respectively. Assume that register $s0, $s1, and the stack pointer ($sp) are
initialized with the values 6, 9, and 800010, respectively. Show stack contents (in decimal) when the stack is at its
maximum size while executing the given code. Do not write register names. Write only numerical contents. Use
X for unknown values.

main () { int evaluate (int a, int b) {


int i = calculate(2,5); int c = square(a) + b; Variable Register content
… return c; c $s0 6
… }
} d $s1 9
int square (int u) { i
Associated
$s2 X
int calculate (int x, int y) { int d = u * u;
return(evaluate (x+y,8)); return d; $sp 800010
} }
Caller function Callee function
Saved/Restored registers ($t0-$t9) ($s0-$s7)
($a0-$a3) $gp,$fp, $sp, $ra
($v0, $v1)
Function Memory MIPs Instructions
Address

main () { 600 Main: addi $a0,$0, 2


604 addi $a1,$0, 5
int i = calculate(2,5);
}
608 jal calculate $ra = 612
612 add $s2, $v0, $0
int calculate (int x, int y) { 700 Calculate: addi $sp, $sp, -4
return(evaluate (x+y,8)); 704 sw $ra, 0($sp)
708 add $a0,$a0, $a1
}
712 addi $a1, $0, 8
716 jal evaluate
$ra = 720
720 lw $ra, 0($sp)
724 addi $sp, $sp, 4
728 jr $ra
int evaluate (int a, int b) { 800 Evaluate: addi $sp, $sp, -12
int c = square(a) + b; 804 sw $ra, 0($sp)
808 sw $a1, 4($sp)
812 sw $s0, 8($sp)
return c;
7980 816 jal square
}
7984
820 lw $a1, 4($sp) $ra = 820
824 add $s0, $v0, $a1
7988 828 add $v0, $s0, $0
7992 832 lw $s0, 8($sp)
836 lw $ra,0($sp)
7996 840 addi $sp, $sp, 12
8000 X 842 jr $ra
int square (int u) { Square:
int d = u * u; return d; } 900 push d
Q17. For the following C code:
a = b + c;
b = a + c;
d = a – b;
Write an equivalent assembly language program in each of the following architectural styles (assume all variables
are initially in memory): Accumulator, Mem-Mem, Stack, and Load-Store

Q18. For each code sequence in Exercise 17, calculate the instruction bytes fetched and the memory data bytes
transferred (read or written). Use the following assumptions about all four instruction sets:

• The opcode is always 1 byte (8 bits).


• All memory addresses are 2 bytes (16 bits).
• All data operands are 4 bytes (32 bits).
• All instructions are an integral number of bytes in length.
• There are no optimizations to reduce memory traffic.

Which architecture is most efficient as measured by code size? Which architecture is most efficient as
measured by total memory bandwidth required (code + data)? If the answers are not the same, why are they
different?
Architectural Style MIPs Instructions Instruction bytes Memory data bytes
fetched transferred

Accumulator load addrB 1+2=3 4

add addrC 3 4
store addrA 3 4

add addrC 3 4
store addrB 3 4
neg 1 0

add addrA 3 4

store addrD 3 4

22 28
a = b + c; Opcode: 1byte
b = a + c; memory addresses: 2 bytes
d = a – b; Operands: 4 bytes Total Memory BW= 50
Architectural Style MIPs Instructions Instruction bytes Memory data bytes
fetched transferred

Memory-memory add addrA, addrB, addrC 1+2+2+2=7 4+4+4=12

add addrB, addrA, addrC 7 12


sub addrD, addrA, addrB 7 12

21 36
a = b + c; Opcode: 1byte
b = a + c; memory addresses: 2 bytes
d = a – b; Operands: 4 bytes Total Memory BW= 57
Architectural Style MIPs Instructions Instruction bytes Memory data bytes
fetched transferred
Stack push addrB 1+2=3 4

push addrC 3 4

add 1 0

dup 1 0
pop addrA 3 4

push addrC 3 4
add 1 0
dup 1 0

pop addrB 3 4

neg 1 0

push addrA 3 4

add 1 0

pop addrD 3 4

27 28
a = b + c; Opcode: 1byte
b = a + c; memory addresses: 2 bytes 55
Total Memory BW=
d = a – b; Operands: 4 bytes
Architectural Style MIPs Instructions Instruction bytes Memory data bytes
fetched transferred

Load-Store lw $t0, 0(addrB) 4 4

lw $t1, 0(addrC) 4 4
add $t2, $t0, $t1 4 0

sw $t2, 0(addrA) 4 4
add $t0, $t2, $t1 4 0
sw $t0, 0(addrB) 4 4

sub $t3, $t2, $t0 4 0

sw $t3, 0(addrD) 4 4

32 20
a = b + c; Opcode: 1byte
b = a + c; memory addresses: 2 bytes
d = a – b; Operands: 4 bytes Total Memory BW= 52
Which architecture is most efficient as measured by code size? Which
architecture is most efficient as measured by total memory bandwidth
required (code + data)? If the answers are not the same, why are they
different?

The load-store architecture :


• It has the lowest amount of data traffic. It has enough registers that it only needs to
read and write each memory location once.
• Since all ALU operations must be separate from loads and stores, and all operations
must specify three registers or one register and one address, the load-store has the
worst code size.
The memory-memory architecture:
• It has the fewest instructions (though also the largest number of bytes per instruction).
• Has the largest number of data accesses.
Midterm 2023
Compile the C-language function:
int sum (int x, int y)
{int z = x + y;
return z;}
into MIPS assembly code. Assume that integer variable z is stored in
register $s0. Use the MIPS pseudoinstructions push and pop, if needed.

push $s0
add $s0, $a0, $a1
add $v0, $s0, $0

pop $s0
jr $ra

You might also like