Assembler: Functions Peripherals basics: driving board Ledstraiola/courses/HLEE503/CM/CM2_FunctionsA... · 2018. 11. 19. · Assembler: Functions Peripherals basics: driving board

Post on 01-Oct-2020

1 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

Transcript

Assembler: FunctionsPeripherals basics: driving board Leds

Marcello Traiolatraiola@lirmm.frUniveristé de Montpellier

November 19, 2018

Marcello TRAIOLA - traiola@lirmm.fr2

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 - traiola@lirmm.fr3

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 - traiola@lirmm.fr4

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 - traiola@lirmm.fr5

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 - traiola@lirmm.fr6

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 - traiola@lirmm.fr7

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 - traiola@lirmm.fr8

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 - traiola@lirmm.fr9

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 - traiola@lirmm.fr10

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 - traiola@lirmm.fr11

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 - traiola@lirmm.fr12

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 - traiola@lirmm.fr13

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 - traiola@lirmm.fr14

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 - traiola@lirmm.fr15

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 - traiola@lirmm.fr16

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 - traiola@lirmm.fr17

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 - traiola@lirmm.fr18

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 - traiola@lirmm.fr19

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 - traiola@lirmm.fr20

Registers role in the ARM Procedure Call Standard

Marcello TRAIOLA - traiola@lirmm.fr21

ASM and C together

ASM and C languages are interoperable!We can call a C function from an ASM code

Marcello TRAIOLA - traiola@lirmm.fr22

ASM and C together

...and call an ASM function from a C code

Marcello TRAIOLA - traiola@lirmm.fr23

Basics on peripherals:Driving Leds on the STM32F3Discovery

Board

Marcello TRAIOLA - traiola@lirmm.fr24

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 - traiola@lirmm.fr25

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 - traiola@lirmm.fr26

Example: Board’s leds

We have to use GPIO port E connected to bus AHBLeds have IDs from 9 to 15

Marcello TRAIOLA - traiola@lirmm.fr27

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 - traiola@lirmm.fr28

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 - traiola@lirmm.fr29

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 - traiola@lirmm.fr30

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].

top related