Upload
others
View
2
Download
0
Embed Size (px)
Citation preview
Assembler: FunctionsPeripherals basics: driving board Leds
Marcello [email protected]é de Montpellier
November 19, 2018
Marcello TRAIOLA - [email protected]
Function Invocation and Return
vo i d f 2 ( vo i d ) {/∗ some code∗/
}vo i d f 1 ( vo i d ) {
f2 ( ) ; /∗ f 1 c a l l s f 2 ∗/}
i n t main ( vo i d ) {
f1 ( ) ; /∗ main c a l l s f 1 ∗/
r e t u r n 0 ;}
Marcello TRAIOLA - [email protected]
Function Invocation and Return. t e x t /∗ S t a r t o f the program code s e c t i o n ∗/
. g l o b a l main /∗ d e c l a r e s the main i d e n t i f i e r ∗/
. g l o b a l f 1 /∗ d e c l a r e s the f1 i d e n t i f i e r ∗/
. g l o b a l f 2 /∗ d e c l a r e s the f2 i d e n t i f i e r ∗/
f2 : /∗ add r e s s o f f 2 f u n c t i o n ∗//∗ some code ∗/
bx l r /∗ Return to the c a l l e r ∗/
f1 : /∗ add r e s s o f f 1 f u n c t i o n ∗/bl f 2 /∗ f 1 c a l l s f u n c t i o n f2 ∗/
bx l r /∗ Return to the c a l l e r ∗/
main : /∗ Addres s o f the main f u n c t i o n ∗/bl f 1 /∗ main c a l l s f u n c t i o n f1 ∗/
bx l r /∗ Return to the c a l l e r ∗/. end /∗ End o f the program ∗/
Marcello TRAIOLA - [email protected]
Function Invocation and Return
The main "jumps" to the address of f1 (bl)I PC = f 1I main’s return address is saved into LR (Link Register)
f1 "jumps" to the address of f2 (bl)I f1’s return address is saved into LR (Link Register)
f2 does its stuff and returns to f1 by means of bx lrI PC = LR
f1 returns to main by means of bx lrI PC = LR
The value of LR must not be modified by the functionI But how can f1 call f2 without losing main’s return
address?
Marcello TRAIOLA - [email protected]
Nested Function correct Invocation
f 2 : /∗ add r e s s o f f 2 f u n c t i o n ∗//∗ some code ∗/
bx l r /∗ Return to the c a l l e r ∗/
f1 : /∗ add r e s s o f f 1 f u n c t i o n ∗/bl f 2 /∗ b e f o r e c a l l i n g f2 , f 1
must save the con t en t o f LR∗/bx l r /∗ Return to the c a l l e r ∗/
main : /∗ Addres s o f the main f u n c t i o n ∗/bl f 1 /∗ main c a l l s f u n c t i o n f1 ∗/bx l r /∗ Return to the c a l l e r ∗/
Since also the main is a function, it has to save the LR register, too
Marcello TRAIOLA - [email protected]
Nested Function correct Invocation
Each function must save the content of LR in the STACKI to do so, we must introduce the push and pop functions
Syntax:I PUSH{cond} reglistI POP{cond} reglist
I cond is an optional condition code (prog. manual, page 64)I reglist is a list of registers (or register ranges), enclosed in
braces.
Restrictions:I PUSH and POP must not involve the stack pointer SP;I The PUSH must not involve the program counter PC;I The POP instruction must not involve LR.
Marcello TRAIOLA - [email protected]
Nested Function correct Invocation
f 1 :mov r4 , l r /∗ save LR in R4 ∗/push { r4 } /∗ save R4 on the s t a c k ∗/
bl f 2
pop { r4 } /∗ r e s t o r e LR in R4 from the s t a c k ∗/mov l r , r4 /∗ r e s t o r e LR ∗/
bx l r
Marcello TRAIOLA - [email protected]
Stack Usage
Procedure Call Standard for the ARM Architecture (AAPCS)assumes a full descending stackI it grows downwards, starting with a high address and
progressing to a lower one.
Stack
SP
4
3
2
1
0
Marcello TRAIOLA - [email protected]
Stack Usage
Stack
SP
push {r4} SP = SP - 4mem[SP] = r4
r4 4
3
2
1
0
For push instructions: decrement SP first and than store thedata.
Marcello TRAIOLA - [email protected]
Stack Usage
Stack
SP
pop {r4} r4 = mem[SP]SP = SP + 4
4
3
2
1
0
For pop instructions: take the data and then increment SP.
Marcello TRAIOLA - [email protected]
Function Arguments and Return Value
Now, let’s look at function’s arguments and return value
C function Example
i n t f a c t o r i a l ( i n t N) {return N!
}
How to transmit the parameters from the caller to the callee?How to return the value from the callee to the caller?
Each architecture has its own calling convention.We are interested in the ARM32 calling convention.
Marcello TRAIOLA - [email protected]
Argument Transmission
In the ARM assembler, the function’s first 4 arguments aretransmitted using registers (r0, r1, r2, r3)The caller has to copy the parameters values in to the registers
The callee has to use the values stored in the registers
Marcello TRAIOLA - [email protected]
Registers Usage
Register Usage Saved byr0 First argument & Return value Callerr1 Second argument Callerr2 Third argument Callerr3 fourth argument Callerr4-r7 Local variables from 1 to 4 CalleeSP Stack Pointer (SP) CalleeLR Link Register (LR) Callee
Marcello TRAIOLA - [email protected]
Argument Transmission and Stackf u n c t i o n :
push { r4−r7 } /∗ save c a l l e r c on t e x t ∗/mov r4 , l rpush { r4 } /∗ save r e t u r n add r e s s ∗/
/∗ some code u s i n g r0 to r3 ∗/
pop { r4 }mov l r , r4 /∗ r e s t o r e r e t u r n add r e s s ∗/pop { r4−r 7 } /∗ r e s t o r e c a l l e r c on t e x t ∗/bx l r /∗ jump back to c a l l e r ∗/
main :/∗ save l r and l o ad pa ramete r s in r0−r3 ∗/
bl f u n c t i o n /∗ jump to f u n c t i o n ∗//∗ r e s t o r e l r ∗/bx l r
Marcello TRAIOLA - [email protected]
Registers Usage
In case of more than 4 parameters you have to use the Stack
/∗ c a l l e r must pas s p5 by means o f the s t a c k ∗/i n t f 1 ( i n t p1 , i n t p2 , i n t p3 , i n t p4 , i n t p5 ) {
}
Marcello TRAIOLA - [email protected]
Example: passing more than 4 parametersf 1 :push { r4−r7 } /∗ save c a l l e r contex ∗/mov r4 , l rpush { r4 } /∗ save c a l l e r r e t u r n add r e s s ∗/
l d r r4 , [ sp , #20] /∗ l o ad the v a l u e o f p5 ∗/pop { r4 }mov l r , r4 /∗ r e s t o r e c a l l e r r e t u r n add r e s s ∗/pop { r4−r7 } /∗ r e s t o r e c a l l e r contex ∗/bx l r
main :/∗ save l r , l o ad r0−r4 w i th pa ramete r s ( p1−p5 )∗/push { r4 } /∗ pas s p5 through the s t a c k ∗/bl f 1pop { r4 }/∗ r e s t o r e l r ∗/bx l r
Marcello TRAIOLA - [email protected]
Transmission by Address
i n t Swap ( i n t ∗a , i n t ∗b ) {i n t tmp ;tmp = ∗b ;∗b = ∗a ;∗a = tmp ;
}
Copy the address of variable a and b in to register r0 and r1
Marcello TRAIOLA - [email protected]
Local Variable Examplef 1 :push { r4−r7 }mov r4 , l rpush { r4 } /∗ save l r ∗/
/∗ per fo rm add r e s s swap∗/
pop { r4 }mov l r , r4pop { r4−r 7 }bx l r
main :
l d r r0 , =al d r r1 , =bbl f 1
Marcello TRAIOLA - [email protected]
Local Variable
In case of lots local variables you have to use the Stack
i n t f 1 ( ) {/∗ the v e c t o r must be s t o r e d in the s t a c k ∗/i n t a [ 1 0 ] ;}
You can use registers from r4 to r7 as local variables, afterhaving saved themYou can additionally use from r8 to r12 (you have to savethem in the stack too)If you need more local variables you have to use the stack (forexample to declare a local array of 50 elements)
Marcello TRAIOLA - [email protected]
Registers role in the ARM Procedure Call Standard
Marcello TRAIOLA - [email protected]
ASM and C together
ASM and C languages are interoperable!We can call a C function from an ASM code
Marcello TRAIOLA - [email protected]
Basics on peripherals:Driving Leds on the STM32F3Discovery
Board
Marcello TRAIOLA - [email protected]
Basics on peripherals
Peripherals are memory mapped in the ARM architectureI Therefore, to drive a peripheral, basically we need to store
specific values to some specific memory locations.
1 Enable the peripheral clock by means of a Reset and clockcontrol (RCC) register
2 Configure the peripheral by means of a Configuration Register
3 Write/read data to/from a Data Register
Marcello TRAIOLA - [email protected]
Example: Board’s leds
1 We have to discover which GPIO port the leds are connectedto
2 We have to discover which bus the GPIO port is connected to
3 We have to activate the corresponding clock, configure theperipheral and finally drive it.
Marcello TRAIOLA - [email protected]
Example: Board’s leds
We have to use GPIO port E connected to bus AHBLeds have IDs from 9 to 15
Marcello TRAIOLA - [email protected]
Example: Board’s leds
Let us configure thecorrect RCC register:RCC_AHBENRWe have to write ‘1’on the bit 21I Value 0x00200000
Address: base +offsetI base =
0x40021000I offset = 0x14I address =
0x40021014
Marcello TRAIOLA - [email protected]
Example: Using on board LEDs
To configure theGPIOE in outputmodeI Value 0x55550000I Address
0x48001000
To write a value inorder to switch on/offLEDsI Value: depends on
the chosen led andoperation
I Address0x48001014
Marcello TRAIOLA - [email protected]
Example: Using on board LEDs
LED_ID VALUE#15 0x00008000#14 0x00004000#13 0x00002000#12 0x00001000#11 0x00000800#10 0x00000400#9 0x00000200#8 0x00000100
Marcello TRAIOLA - [email protected]
Example: Using on board LEDs. equ RCC_AHBENR, 0 x40021014. equ GPIOE_MODER, 0 x48001000. equ GPIOE_ODR, 0 x48001014
. t e x t
. g l o b a l HW_init
HW_init :
movw r0 , #: lower16 :RCC_AHBENRmovt r0 , #:upper16 :RCC_AHBENRl d r r1 , [ r0 ] // con t en t o f RCC_AHBENRmovw r2 , #: lower16 : 0 x00200000movt r2 , #:upper16 : 0 x00200000
o r r r1 , r1 , r2s t r r1 , [ r0 ]movw r0 , #: lower16 :GPIOE_MODERmovt r0 , #:upper16 :GPIOE_MODERmovw r1 , #: lower16 : 0 x55550000movt r1 , #:upper16 : 0 x55550000s t r r1 , [ r0 ]
bx l r
MOVT: Move top
MOVT Rd, #imm16
MOVT writes a 16-bitimmediate value, imm16,to the top halfword,Rd[31:16], of itsdestination register. Thewrite does not affectRd[15:0].