Nested Procedures

jabgoldfishAI and Robotics

Oct 19, 2013 (3 years and 9 months ago)

74 views

1

Nested Procedures


Procedures that don't call others are called
leaf

procedures, procedures that call others are called
nested

procedures.


Problems may arise now, for example the main
program calls procedure A with the argument 3 in
$a0

and the return address in
$ra
. Procedure A
then calls procedure B with the argument 7 in
$a0

and with its return address in
$ra
. We must
preserve these values across calls.


Lets look at a translation of the recursive factorial
function in C.

2

Factorial in C

int fact(int n)

{


if(n < 1)



return (1);


else



return (n * fact
-
1);

}


As we can C the function calls itself multiple times.


The argument
n

is sent to the function via the
register
$a0
, which is saved on the stack along with
$ra
.

3

Factorial in Assembly

fact: subi $sp,$sp,
8
# make room for
2
items


sw $ra,
4
($sp)# push the return address


sw $a
0
,
0
($sp)# push the argument n


slt $t
0
,$a
0
,
1
# test for n<
1


beq $t
0
,$zero,L
1
# if n>=
1
goto L
1


li $v
0
,
1
# pseudoinstruction $v
0
=
1


addi $sp,$sp,
8
# pop
2
items off stack


jr $ra

The following is the recursive call to fact(n
-
1
)

L
1
: subi $a
0
,$a
0
,
1
# n
--


jal fact # call fact(n
-
1
)


lw $a
0
,
0
($sp) # return from fact(n
-
1
)


lw $ra,
4
($sp) # pop n and return address


addi $sp,$sp,
8
# pop
2
items off stack


mult $v
0
,$a
0
,$v
0
# return n * fact(n
-
1
)


jr $ra

4

Procedure Frame


The stack above
$sp

is preserved (
רמשנ

)
by
making sure that the callee (
תארקנ היצקנופ

)
is
doesn't write above
$sp
.


$sp

is preserved by adding exactly the same
amount subtracted from it.


All other registers are preserved by being saved on
the stack.


The stack also contains local variables that don't fit
into registers.


The segment of the stack containing the saved
registers and local variables is called the
procedure
frame
or

activation record.

5

Frame Pointer


Some MIPS software use the register $fp to point to
the first word of the frame of a procedure.

6

Static and Automatic Variables


C++ has two storage classes for variables
automatic

and
static
.


Automatic variables are local to a function and are
deleted when the function exits.


Static variables exist across function calls. Global C
variables are static, as well as any variables
defined with the keyword
static.
All other
variables are automatic.


MIPS software reserves a register called the
global
pointer
or
$gp.
Static variables are accessed
through this register.

7

Characters and Bytes


Most computers today use
8
-
bit bytes to represent
characters, with the American Standard Code for
Information Interchange (ASCII) being the most
common representation.


MIPS provides special instruction to move bytes:

lb $t
0
,
0
($sp) # read byte from memory

sb $t
0
,
0
($gp) # write byte to memory


lb
loads a byte from memory into the rightmost
8
bits of the register.
sb

takes a byte from the
8
rightmost bits in the register and stores them in
memory.

8

Strcpy in C++

void strcpy(char x[], char y[])

{


int i;


i=
0
;


while((x[i]=y[i]) !=
0
)



i++

}


The base address for the arrays
x
and

y

are in
registers
$a
0
and

$a
1
.

9

Strcpy in Assembly

strcpy:


add $t
0
,$zero,$zero #$t
0
=
0

L
1
: add $t
1
,$a
1
,$t
0
#$t
1
=&y[i]


lb $t
2
,
0
($t
1
) # $t
2
=y[i]


add $t
3
,$a
0
,$t
0
#$t
3
=&x[i]


sb $t
2
,
0
($t
3
) # x[i]=y[i]


addi $t
0
,$t
0
,
1
# i++


bne $t
2
,$zero,L
1
# if y[i]!=
0
loop


jr $ra # return


10

Immediate Operands


As mentioned before the I
-
format instruction contains a
16
bit constant called an
immediate
. Using I
-
type
instructions avoids loading values from memory into a
register. Examples of instruction which use immediate
values are:

multi $s
0
,$s
1
,
4
# $s
0
=$s
1
*
4

slti $t
0
,$s
2
,
10
# $t
0
=
1
if $s
2
<
10


But if a constant is larger than
16
bits? MIPS provides
an instruction
lui

that loads a
16
bit constant into the
upper half of an register.

In order to load the value:

0000 0000 0011 1101 0000 1001 0000 0000

into $s
0
we must perfrom:

lui $s
0
,
61
#
61
d =
0000 0000 0011 1101

addi $s
0
,$s
0
,
2304
#

2304
d =
0000100100000000

11

Addressing in Branchs and Jumps


j 10000 # go to location 10000

Jumps to the address 10000 in memory.


2 10000


6 bits (opcode) 26 bits (address)


bne $s0,$s1,Exit # branch if $s0!=$s1


5 16 17 Exit


6 bits 5 bits 5 bits 16 bits (address)


If addresses of the program have to fit into a 16
-
bit
field no program could be larger than 64KByte
which is unrealistic. An alternative would to specify
a register which would be added to the branch
address. But which register?

12

PC
-
Relative Adressing


The
Program Counter
(PC) is a register the
software can't access directly, that always contains
the address of the current instruction being
executed. Thus if we use the PC as the register to
add to the branch address we can always branch
within a range of
-
2
15

to 2
15

bytes of the current
instruction.


This is enough for most loops and
if
statements.
This form of addressing is called
PC
-
relative
addressing.


Procedures are not usually within a short range of
the current instruction and thus
jal

is a J
-
type
instruction

13

Branch Offset in Machine Language


Lets look at a loop in assembly:

Loop: .


.


bne $t
0
,$t
1
,Exit


subi $t
0
,$t
0
,
1


j Loop

Exit:


The machine code of the
bne

instruction is:


5 8 9 8


The branch instruction adds
8
bytes to the PC and not
12
because the PC is automatically incremented by
4
when an instruction is executed.


In fact the branch offset is
2
not
8
. All MIPS instructions
are
4
bytes long thus the offset is in
words
not bytes.
The range of a branch has been multiplied by
4
.

14

Pseudodirect Addressing


The
26
-
bit field in the jump instruction is also a
word address. Thus it is a
28
-
bit address. But the
PC holds
32
-
bits?


The MIPS jumps instruction replaces only the lower
28
bits of the PC, leaving the
4
highest bits of the
PC unchanged.


The loader and linker must avoid placing a program
across an address boundary (
לובג

) of
256
MB (
64
million instructions). Otherwise a
j

must be
replaced with a
jr.

15

Addressing Mode Summary


Immediate addressing

-

the Operand is a constant


Register addressing

-

the Operand is a register


Base or displacement addressing

-

the operand is
is at the memory location whose address is the
sum of a register and a constant in the instruction.


PC
-
relative addressing

-

the address is the sum of
the PC and a constant in the instruction.


Pseudodirect addressing

-

the jump address is the
26
bits of the instruction concatenated (
ףרוצמ

)
to
the upper bits of the PC.

16

Addressing Modes (picture)

17

The Intel
80
x
86


MIPS was the vision of a single group in
1985
, all
pieces fit together nicely.


Such is not the case with the
80
x
86
. It is the
product of several independent groups who
evolved the architecture over
20
years: Here are
important
80
x
86
milestones:


1978
-

8086
a
16
bit microprocessor introduced

1980
-

8087
floating
-
point coprocessor

1982
-

80286
extends the memory to
24
bits

1885
-

80386
is a true
32
bit processor

1989
-
95
-

80486
, Pentium (
92
) and Pentium Pro (
95
) add
more performance

1997
-

MMX expands instruction set for multi
-
media

1997
-
99
-

Pentium II and III add more power

18

80
x
86
Registers

19

Typical
80
x
86
Instructions

20

80
x
86
Instruction Formats