EE 319K�Introduction to Embedded Systems
Lecture 9: Stack and Local Variables, Fixed-Point Numbers
Bard, Cuevas, Erez, Gerstlauer, Holt, Valvano, Yerraballi, Telang, Tiwari
9-1
Agenda
Agenda
Next time
Bard, Cuevas, Erez, Gerstlauer, Holt, Valvano, Yerraballi, Telang, Tiwari
9-2
LCD – Lab7
Bard, Cuevas, Erez, Gerstlauer, Holt, Valvano, Yerraballi, Telang, Tiwari
9-3
Local Variables
Bard, Cuevas, Erez, Gerstlauer, Holt, Valvano, Yerraballi, Telang, Tiwari
9-4
Local Variables
Bard, Cuevas, Erez, Gerstlauer, Holt, Valvano, Yerraballi, Telang, Tiwari
9-5
Variables in C
��
���
��
Reduce the scope as much as possible: need to know basis
9-6
Globals in C
��
���
��
// accessible by all modules �int16_t myGlobalVariable;
// accessible this file only�static int16_t myPrivateStaticVariable;
void MyFunction(void){� int16_t myLocalVariable;
static int16_t count=0;
count++; �}
�
9-7
Local-automatic in C
Local - Automatic
// accessible by all modules �int16_t myGlobalVariable;
// accessible this file only�static int16_t myPrivateStaticVariable;
void MyFunction(void){� int16_t myLocalVariable;
static int16_t count=0;
count++; �}
�
9-8
Static in C
File-private static
���
// accessible by all modules �int16_t myGlobalVariable;
// accessible this file only�static int16_t myPrivateStaticVariable;
void MyFunction(void){� int16_t myLocalVariable;
static int16_t count=0;
count++; �}
�
9-9
Static in C
Reduce the scope as much as possible: need to know basis
// accessible by all modules �int16_t myGlobalVariable;
// accessible this file only�static int16_t myPrivateStaticVariable;
void MyFunction(void){� int16_t myLocalVariable;
static int16_t count=0;
count++; �}
�
9-10
Functions in C
���
// callable by other �// routines in this file only �void static MyPrivateFunction(void){…}
// callable by all modules �void SysTick_Init(void){…}
Bard, Cuevas Erez, Gerstlauer, Holt, Valvano, Yerraballi, Telang, Tiwari
9-11
Why use Locals?
Why use Stack? Why use Registers?
Bard, Cuevas, Erez, Gerstlauer, Holt, Valvano, Yerraballi, Telang, Tiwari
9-12
Recall Stack Rules
Push
Pop
9-13
Variables on the stack
void play_note(uint16_b pitch,
uint16_b duration,
uint16_b loud_left,
uint16_b loud_right,
uint16_b timber_idx,
uint16_b attack_rate,
uint16_b attack_type,
uint16_b decay_rate,
uint16_b decay_type);
void Function(void){char Buffer[100];
}
9-14
Local variables using Registers
; *****binding phase*********** sum RN 4 ;32-bit unsigned n RN 5 ;32-bit unsigned ; 1)**** no allocation phase ** Calc PUSH {R4,R5} MOV n,R0 ; 2)******access phase ******** MOV sum,#0 loop ADD sum,sum,n ;sum+n SUBS n,n,#1 ;n-1 BNE loop ; 3)***no deallocation phase ** MOV R0,sum POP {R4,R5} BX LR ;R0=sum | // input: n 32-bit number // output: n+(n-1)+(n-2)+...+2+1 uint32_t Calc(uint32_t n) { uint32_t sum; sum = 0; do{ sum=sum+n; n--; } while(n>0); return sum; } |
R4 sum
R5 n
Use R4-R11 as locals when this function calls another, because the other function by AAPCS will preserve the values of R4-R11
Use R0-R3,R12 as locals when this function doesn’t call another function, because you do not need to preserve R0-R3,R12
The correct Lab 7 solutions have no PUSH and POP during access phase
9-15
Stack frame using SP
SUB SP,SP,#16
STR R0,[SP,#y]
ADD SP,SP,#16
y EQU 8
9-16
Stack frame using SP
; *****binding phase*************** sum EQU 0 ;32-bit unsigned number n EQU 4 ;32-bit unsigned number ; 1)*****allocation phase ********* Calc PUSH {R0} ;allocate, init n SUB SP,#4 ;allocate sum ; 2)******access phase ************ MOV R0,#0 STR R0,[SP,#sum] ;sum=0 loop LDR R1,[SP,#n] ;R1=n LDR R0,[SP,#sum] ;R0=sum ADD R0,R0,R1 ;R0=sum+n STR R0,[SP,sum] ;sum=sum+n LDR R1,[SP,#n] ;R1=n SUBS R1,R1,#1 ;n-1 STR R1,[SP,#n] ;n=n-1 BNE loop ; 3)******deallocation phase ***** LDR R0,[SP,#sum] ;R0=sum ADD SP,#8 ;deallocation BX LR ;R0=sum | // input: n 32-bit number // output: n+(n-1)+(n-2)+...+2+1 uint32_t Calc(uint32_t n) { uint32_t sum; sum = 0; do{ sum=sum+n; n--; } while(n>0); return sum; } |
Stack pointer implementation of a function with two local 32-bit variables.
9-17
Frame pointer using R11
; *****binding phase*************** sum EQU 0 ;32-bit unsigned number n EQU 4 ;32-bit unsigned number ; 1)*****allocation phase ********* calc PUSH {R4,R5,R11,LR} SUB SP,#8 ;allocate n,sum MOV R11,SP ;frame pointer ; 2)******access phase ************ MOV R0,#0 STR R0,[R11,#sum] ;sum=0 MOV R1,#1000 STR R1,[R11,#n] ;n=1000 loop LDR R1,[R11,#n] ;R1=n LDR R0,[R11,#sum] ;R0=sum ADD R0,R1 ;R0=sum+n STR R0,[R11,sum] ;sum=sum+n LDR R1,[R11,#n] ;R1=n SUBS R1,#1 ;n-1 STR R1,[R11,#n] ;n=n-1 BNE loop ; 3)******deallocation phase ***** ADD SP,#8 ;deallocation POP {R4,R5,R11,PC} ;R0=sum | uint32_t calc(void){ uint32_t sum,n; sum = 0; for(n=1000;n>0;n--){ sum=sum+n; } return sum; } |
Frame pointer implementation of a function with two local 32-bit variables.
9-18
Push parameters on stack
; Inputs R0 is x ; R1 is y ; R2 is z ; Output R0 is return value sum EQU 0 ;32-bit signed number x EQU 4 ;32-bit signed number y EQU 8 ;32-bit signed number z EQU 12 ;32-bit signed number Add3 PUSH {R0,R1,R2,LR} SUB SP,#4 ;allocate sum ; body of the function LDR R0,[SP,#x] ADD R0,R0,[SP,#y] ADD R0,R0,[SP,#z] STR R0,[SP,#sum] ADD SP,#16 ;deallocate POP {PC} | int32_t Add3(int32_t x, int32_t y, int32_t z) { int32_t sum; sum = x+y+z; return sum; } |
Pushing parameters on stack makes them similar to local variables
9-19
Example using SP
uint32_t Example2(uint32_t x){
uint32_t z;
…
z = x+1;
…
return z;
}
9-20
Example using SP
void Example3(void){
char buffer[16];
int i;
i=15;
do{
buffer[i]=0;
i--;
}while (i>=0);
}
9-21
Example using R11
void Example3(void){
char buffer[16];
int i;
i=15;
do{
buffer[i]=0;
i--;
}while (i>=0);
}
9-22
Fixed-Point Numbers
Why? (wish to represent non-integer values)
When? (range is known, range is small)
Bard, Cuevas, Erez, Gerstlauer, Holt, Valvano, Yerraballi, Telang, Tiwari
9-23
Fixed-Point Numbers
How? (value = I*Δ)
(What about negative numbers?)
Bard, Cuevas, Erez, Gerstlauer, Holt, Valvano, Yerraballi, Telang, Tiwari
9-24
Fixed-Point Numbers: Decimal
Decimal Fixed-Point
(Value = I*10m)
I is a 16-bit unsigned integer (variable integer)
Δ = 10m decimal fixed-point (fixed constant)
For example, with m=-3 (resolution of 0.001 or milli) the value range is 0.000 to 65.535 (with 16-bit)
What is 𝜋 represented as, in Decimal Fixed-Point?� 𝜋 (3.14159…) = I*10-3 � => I = Integer approximation of (3.14159…*103)
I = Integer approximation of (3141.59)
I = 3142
Decimal Fixed-Point numbers are human-friendly
-easy to input/output to humans
Bard, Cuevas, Erez, Gerstlauer, Holt, Valvano, Yerraballi, Telang, Tiwari
9-25
Fixed-Point Numbers: Binary
Binary Fixed-Point
(Value = I*2m)
I is a 16-bit unsigned integer (variable integer)
Δ = 2m binary fixed-point (fixed constant)
For example with m=-8 (resolution of 1/256)
What is 𝜋 represented as, in binary Fixed Point?
𝜋 (3.14159…)= I*2-8
=> I = Integer approximation of (3.14159…*28)
I = Integer approximation of (804.2477) � I = 804
Binary Fixed-Point numbers are computer-friendly
-runs very fast because shifting is fast
Bard, Cuevas, Erez, Gerstlauer, Holt, Valvano, Yerraballi, Telang, Tiwari
9-26
Examples
How do we store the value 1.2 cm?
How do we store the value 1.2 cm?
How do we store the value 1.2 cm?
9-27
Review
Range is 0 to 100 gal, resolution 0.0001 gal
If interfacing to computers, should we use decimal or binary?
What is Δ?
What C variable type?
Why?
If interfacing to humans, should we use decimal or binary?
What is Δ?
What C variable type?
Why?
9-28