AVRASSEMBLY PROGRAMMING Procedure Calls

Assembly Language Programming
4/28/2015
AVRASSEMBLY PROGRAMMING
Procedure Calls
Dr. Tim Margush
1
Assembly Language Programming
4/28/2015
PROCEDURE CALLS
uint8_t addone (uint8_t X)
{ uint8_t sum;
sum = X + 1;
return (sum);
}
main ()
{ uint8_t var1, var2;
var1 = 50; var2 = addone (var1);
}
Dr. Tim Margush
2
2
Assembly Language Programming
4/28/2015
SEVERAL NEW ISSUES


Where do we return to after the procedure call is
done?
Where are the local variables of the procedure
kept?

How are the parameters passed?

How is the result returned?
3
Dr. Tim Margush
3
Assembly Language Programming
4/28/2015
RETURN ADDRESS
We need to keep the return address somewhere?
 #return addresses that need to be remembered?



How many instances of local variables per
procedure? Can a procedure be called
(instantiated) multiple times?
Stack.
4
Dr. Tim Margush
4
Assembly Language Programming
4/28/2015
STACK
 The
stack grows downward from a high
address to a low address.

Special instructions and I/O register support
stack access:
RET, CALL, PUSH, POP, …
 SP (Stack Pointer)


The stack requires initialization


Set SP to an appropriate address (empty stack)
The stack is managed by application and is
also used by the processor interrupt system
5
Dr. Tim Margush
5
Assembly Language Programming
4/28/2015
STACK INITIALIZATION
 Typically,
the stack starts at the highest
SRAM address and grows downward
through memory
 SP points to the next available byte of
stack storage (top of stack after a push)
ldi R16, high(RAMEND)
out SPH, R16
ldi R16, low(RAMEND)
out SPL, R16
Dr. Tim Margush
$100
SRAM
SP
$1FFF
Stack
6
6
Assembly Language Programming
4/28/2015
SP IN SRAM (ADDRESS)
The I/O addresses are 0x3D and 0x3E on
ATmega128 (to use IN/OUT)
The memory addresses are 0x5D and 0x5E (to use
LDS/STS)
7
Dr. Tim Margush
7
Assembly Language Programming
4/28/2015
PUSH AND POP




push Rr
Register data copied
to byte at address in
SP.
SP is decremented.
2 cycles




pop Rd
SP is incremented.
Byte at address in SP
is copied to Rd.
2 cycles
8
Dr. Tim Margush
8
Assembly Language Programming
4/28/2015
PUSH OPERATION
push R2
Addr
R2: 0xAB
Byte
Addr
Byte
0x1300 0x00
0x1300 0x00
0x12ff
0x11
0x12ff
0x11
0x12fe
0x22
0x12fe
0x22
0x12fd 0xAB
SPH: 0x12
SPL: 0xfd
SPL: 0xfc
9
Dr. Tim Margush
9
Assembly Language Programming
4/28/2015
POP OPERATION
pop R3
Addr
R3: 0x00
Byte
Addr
Byte
0x1300 0x00
0x1300 0x00
0x12ff
0x11
0x12ff
0x11
0x12fe
0x22
0x12fe
0x22
SPH: 0x12
SPL: 0xfd
SPL: 0xfe
R3: 0x22
Dr. Tim Margush
10
10
Assembly Language Programming
4/28/2015
PROCEDURE CALL
R16
R17
main ()
{ uint8_t var1, var2;
var1 = 50;
var2 = addone (var1);
}
main: ----------------ldi R16, 50 ;var1 = 50
;pass parameters on
;stack left to right
push R16
rcall addone
-----------rcall: jumps to label
----------- Relative addressing
 Pushes the address of the
next instruction on the stack.
Return address (RA)
Dr. Tim Margush
11
11
Assembly Language Programming
4/28/2015
FUNCTION CALL AND RETURN
SP register: Stack Pointer register
Before RCALL After RCALL
High
end
SP
ret addr.
Other
Data
Low
end
Data Memory
next
addr.
Other
Data
main
RCALL
…
…
addone
ret
Data Memory
Program Memory
Dr. Tim Margush
12
Assembly Language Programming
4/28/2015
STACK FOR MAIN
Stack frame for
main:
Local vars
Any saved vars
Proc call paras
var1
var2
SP:0x1200
Dr. Tim Margush
13
13
Assembly Language Programming
4/28/2015
push R16
var1
var2
50
SP:0x11ff
Dr. Tim Margush
14
14
Assembly Language Programming
4/28/2015
rcall addone
var1
var2
0x4000: ldi r16, 50
0x4002: push r16
0x4004: rcall addone
0x4006: something
PC: 0x4004
50
RAL: 0x06
RAH: 0x40
SP:0x11fd
15
PC: address of addone: 0x4400
Dr. Tim Margush
15
Assembly Language Programming
4/28/2015
PROCEDURE ADDONE
uint8_t addone (int
X)
{ uint8_t sum;
sum = X + 1;
return (sum);
}
addone: in YH, SPH
in YL, SPL
; Now on Y serves as an
; entry point into stack
16
Dr. Tim Margush
16
Assembly Language Programming
ldd R1, Y+3
; what if R1 is used by the
; caller – main?
Y: R28:29: 0x11fd
Dr. Tim Margush
var1
var2
50
RAL: 0x06
RAH: 0x40
SP:0x11fd
Stack frame for addone
addone: in YH, SPH
in YL, SPL
; Now on Y serves as an
; entry point into stack
;Now move var X into reg.
4/28/2015
17
17
Assembly Language Programming
var1
var2
50
RAL: 0x06
RAH: 0x40
Saved R1
Y: R28:29: 0x11fd
Dr. Tim Margush
SP:0x11fc
Stack frame for addone
addone: in YH, SPH
in YL, SPL
; save R1 before using it
push R1
ldd R1, Y+3
; sum = X+1
; where is sum?
; on the stack.
4/28/2015
18
18
Assembly Language Programming
Y: R28:29: 0x11fd
Dr. Tim Margush
var1
var2
50 (51)
RAL: 0x06
RAH: 0x40
sum (local vars):
51
Saved R1
SP:0x11fb
Stack frame for addone
addone: in YH, SPH
in YL, SPL
; skip over local vars
push zero
; save R1 before using it
push R1
ldd R1, Y+3
; sum = X+1
inc R1
st Y, R1
; return result – where?
; overwrite input para
std Y+3, R1
4/28/2015
19
19
Assembly Language Programming
; now we return with RET
var1
var2
50 (51)
RAL: 0x06
RAH: 0x40
sum (local vars)
Saved R1
Y: R28:29: 0x11fd
Dr. Tim Margush
SP:0x11fb (11fc)(11fd)
Stack frame for addone
; return result – where?
; overwrite input para
std Y+3, R1
; now undo everything
; restore R1
pop R1
; skip over local vars
out SPH, YH
out SPL, YL
4/28/2015
20
20
Assembly Language Programming
; now we return with RET
ret
var1
var2
51
RAL: 0x06
RAH: 0x40
PC: 0x4006
SP: 11fd
Dr. Tim Margush
Stack frame for addone
; return result – where?
; overwrite input para
std Y+3, R1
; now undo everything
; restore R1
pop R1
; skip over local vars
out SPH, YH
out SPL, YL
4/28/2015
21
21
Assembly Language Programming
addone: in YH, SPH
in YL, SPL
; skip over local vars
push zero
; save R1 before using it
push R1
ldd R1, Y+3
; sum =inc
inc R1
st Y, R1 ; sum =inc
; overwrite input para
std Y+3, R1
; now undo everything
; restore R1
pop R1
4/28/2015
; skip over local vars
out SPH, YH
out SPL, YL
; now we return with RET
ret
22
Dr. Tim Margush
22
Assembly Language Programming
4/28/2015
COMPLETE “MAIN”
var1
main: ----------------ldi R16, 50 ;var1 = 50
;pass parameters on
;stack left to right
push R16
rcall addone
;read the result
; var2 <- result
pop R17
Dr. Tim Margush
var2
51
SP: 11ff (1200)
23
23
Assembly Language Programming
4/28/2015
AVR-GCC CALL CONVENTION
Function parameters
R25:R24, R23:R22, ..., R9:R8
 All aligned to start in even-numbered register
i.e. char will take two registers (use the even one)
 A long type uses two pairs
 Extra parameters go to stack

Function return values
8-bit in r24 (with r25 cleared to zero), or
 16-bit in R25:R24, or
 32-bit in R25-R22, or
 64-bit in R25-R18

Dr. Tim Margush
24
Assembly Language Programming
4/28/2015
AVR-GCC CALL CONVENTION
How to share register usage?
Call-saved/Callee-save/Non-volatile: R2-R17, R28-R29
Caller may use them for free (save registers)
Call-used/Caller-save/Volatile: R18-R27, R30-R31
Callee may use them for free (temp registers)
Fixed registers
R0: Temporary register used by gcc (no need to save)
 R1: Should be zero

Dr. Tim Margush
25
Assembly Language Programming
4/28/2015
AVR-GCC CALL CONVENTION
R0
R1 (Zero)
R2
R3
R4
R5
R6
R7
R8 (P8)
R9 (P8)
R10 (P7)
R11 (P7)
R12 (P6)
R13 (P6)
R14 (P5)
R15 (P5)
R16 (P4)
R24 (P0, V0)
R17 (P4, V8) R25 (P0, V1)
R18 (P3, V6)
R26
X
R19 (P3, V7)
R27
R20 (P2, V4)
R28
Y
R21 (P2, V5)
R29
R22 (P1, V2)
R30
Z
R23 (P1, V3)
R31
Call-saved/Callee-save/Non-volatile
Call-used/Caller-save/Volatile
Fixed
Dr. Tim Margush
P: Parameter
V: Result
26
Assembly Language Programming
4/28/2015
AVR-GCC CALL CONVENTION
Where are the parameters and return values?
char add_char(char a, char b);
int checksum(int A[],
int size);
char add_3char(char a, char b, char c);
Dr. Tim Margush
27
Assembly Language Programming
4/28/2015
FUNCTION EXAMPLE
; char add_char(char a, char b)
; reg: r24 for a, r22 for b
add_char:
ADD r24, r22 ; r24=a+b
LDI r25, 0
; clear r25
RET
main:
…
LDI r24, 0x01 ; load a
LDI r22, 0x02 ; load b
RCALL add_char
; c=a+b
ST
X, r24
; save c
Dr. Tim Margush
28
Assembly Language Programming
4/28/2015
FUNCTION EXAMPLE
// assume size is greater than zero
//parity check - ExOR
char checksum(char A[], int size);
Dr. Tim Margush
29
Assembly Language Programming
4/28/2015
FUNCTION EXAMPLE
; parameter r25:r24 for A,r23:r22 for
size,
; Use Y for &A[k], r24 for csum
; r23:r22 for i, r20 for A[i]
; return value in r25:r24
checksum:
; func prologue
PUSH
r29
; save r29
PUSH
r28
; save r28
; loop prologue
MOVW
r28, r24
; reg Y=&A[0]
CLR
r24
; csum = 0;
Dr. Tim Margush
30
Assembly Language Programming
4/28/2015
FUNCTION EXAMPLE
loop:
LD
EOR
SUBI
BNE
; func
CLR
r25:r24
POP
POP
RET
Dr. Tim Margush
r20, Y+
; load A[k]
r24, r20
; csum^=A[k]
r22, 1 ; size-loop
; cont until i==0
epilogue
r25
; ret value in
r28
r29
; restore r28
; restore r29
31
Assembly Language Programming
4/28/2015
FUNCTION EXAMPLE
char add_3char(char a, char b, char c)
{
return add_char(add_char(a, b), c);
}
Dr. Tim Margush
32
Assembly Language Programming
4/28/2015
FUNCTION EXAMPLE
; parameters: r24=a, r22=b, r20=c
add_3char:
PUSH
r20
; r20 is
volatile
; call add_char(a, b)
RCALL add_char
; call add_char(ret_value, c)
POP
r22
; make c a
param.
RCALL add_char
RET
Dr. Tim Margush
33
Assembly Language Programming
4/28/2015
SUMMARY
We have learned AVR-GCC Call Convention





Make function call (caller) and return (callee)
Pass parameters (caller and callee)
Get return value (caller)
Share registers (caller and callee)
Use stack
This is how one function can call another function
by prototype, with no need for the source code
Dr. Tim Margush
34