Study Web

Week 7

ASM Programming: Turn on an LED (Part 1)

COS10004 Computer Systems · Lecture 7.4 ASM Programming: Turn on an LED (Part 1)

- ASM basics

TURNING ON A LIGHT!

  • We are now ready to program, so lets start playing!
  • We’re going to walk through the asm code for turning on an LED connected to a pin

FIRST WE WIRE IT UP

See https://www.youtube.com/watch?v=Rd9kvVs1lSQ for my tutorial on wiring this circuit

We “write” bits to the LED via this pin

See https://www.youtube.com/watch?v=Rd9kvVs1lSQ for my tutorial on wiring this circuit

This is the ground pin

We “write” bits to the LED via this pin

See https://www.youtube.com/watch?v=Rd9kvVs1lSQ for my tutorial on wiring this circuit
  • Lets look at the code in FASMARM first, then unpack how it works

TURNING ON AN LED

BASE = $FE000000 ; $ means HEX
GPIO_OFFSET=$200000

mov r0,BASE
orr r0,GPIO_OFFSET ;r0 now equals 0xFE200000

mov r1,#1
lsl r1,#24 ;write 1 into r1, lsl 24 times to move the 1 to bit 24
str r1,[r0,#4] ;write it into 5th (16/4+1)block of function register

mov r1,#1
lsl r1,#18 ;write 1 into r1, lsl 18 times to move the 1 to bit 18
str r1,[r0,#28] ;write it into first block of pull-up register

loop$: b loop$;loop forever

TURNING ON AN LED

We can set constants.

BASE = $FE000000 ; $ means HEX
GPIO_OFFSET=$200000 The name on the left must

be a unique name. Make it

mov r0,BASE sensible so you know what it
orr r0,GPIO_OFFSET ;r0 now equals 0xFE200000 represents.

mov r1,#1
lsl r1,#24 ;write 1 into r1, lsl 24 times to move the 1 to bit 24
str r1,[r0,#4] ;write it into 5th (16/4+1)block of function register The value on the right can be

expressed as a decimal value

mov r1,#1 or HEX.
lsl r1,#18 ;write 1 into r1, lsl 18 times to move the 1 to bit 18
str r1,[r0,#28] ;write it into first block of pull-up register Decimal starts with a #

loop$: Hex values start with a $ b loop$;loop forever

BASE = $FE000000 ; $ means HEX Instructions to execute.
GPIO_OFFSET=$200000

Here you can see the

mov r0,BASE following instructions
orr r0,GPIO_OFFSET ;r0 now equals 0xFE200000 being used:

Mov, orr, lsl, str, b

mov r1,#1
lsl r1,#24 ;write 1 into r1, lsl 24 times to move the 1 to bit 24 We’ll look at them in more
str r1,[r0,#4] ;write it into 5th (16/4+1)block of function register detail shortly

mov r1,#1
lsl r1,#18 ;write 1 into r1, lsl 18 times to move the 1 to bit 18
str r1,[r0,#28] ;write it into first block of pull-up register

loop$: b loop$;loop forever

TURNING ON AN LED

BASE = $FE000000 ; $ means HEX
GPIO_OFFSET=$200000

mov r0,BASE
orr r0,GPIO_OFFSET ;r0 now equals 0xFE200000

mov r1,#1
lsl r1,#24 ;write 1 into r1, lsl 24 times to move the 1 to bit 24 In-line comments (non
str r1,[r0,#4] ;write it into 5th (16/4+1)block of function register executable) start with a semi

colon

mov r1,#1
lsl r1,#18 ;write 1 into r1, lsl 18 times to move the 1 to bit 18 Use these to make your code
str r1,[r0,#28] ;write it into first block of pull-up register Easily readable and

interpretable loop$: b loop$;loop forever

BASE = $FE000000 ; $ means HEX
GPIO_OFFSET=$200000

mov r0,BASE Labels mark a location (an
orr r0,GPIO_OFFSET ;r0 now equals 0xFE200000 actual address!) in your asm

code.

mov r1,#1
lsl r1,#24 ;write 1 into r1, lsl 24 times to move the 1 to bit 24 They are uniquely named
str r1,[r0,#4] ;write it into 5th (16/4+1)block of function register and end with a colon.

mov r1,#1 These allow you to jump
lsl r1,#18 ;write 1 into r1, lsl 18 times to move the 1 to bit 18 from one location to another
str r1,[r0,#28] ;write it into first block of pull-up register in your code

(eg. for looping, branching loop$: b loop$;loop forever function calls etc)

In this case its being used as part of an infinite loop..but why?

ASSEMBLY

mov;move value into register (does not require RAM)* lsl;logical left shift (double a number n times) str;store (write) value from register to a memory location Loop:;a label** b;branch (goto)

*mov cannot be used to represent some 32-bit numbers. The alternative is ldr, which we will cover later. For more explanations look here:

http://stackoverflow.com/questions/14046686/why-use-ldr-over-mov-or-vice- versa-in-arm-assembly

**In some ASM the word loop is reserved, so people use loop$, l00p, loop2 etc.

delimiter

MOVE

mov r1,#1

register 1 value in decimal

literal value

(not a pointer)

  • load register 1 with the value 1*

*not all numbers can be used

delimiter

OR

orr r1,$21

register 1 value in

HEX

operand (may be a register,

pointer, • r1 = r1 OR operand

literal)

  • Adds two numbers together without possibility of overflow or carry operations

delimiter

LOGICAL SHIFT LEFT

lsl r1,#21

register 1 value in decimal

literal value

(not a pointer) • logical shift left (double) register 1 21 times

  • (multiply by 221)
  • (r1 = 2097152 = 0x200000)
  • (bit 21 is set)
  • (00000000 00100000 00000000 00000000)

BRANCH

  • Loop: label
  • b Loop

branch label (could also use a (goto) where to memory address if we go knew where the code was loaded)

  • loop forever
  • stops it from crashing

delimiter

STORE REGISTER

str r1,[r0,#16]

register 1 offset value in decimal

reference

(a pointer)

  • write value r1 into the memory location: 16 bytes after the value in r0
  • [0x20200010] = 0x200000

delimiter

LOAD REGISTER

ldr r0,[r1]

r1 must contain a

pointer to a value in memory

  • load register 0 with the value pointed to by r1

GENERAL PURPOSE REGISTERS

  • The Armv7 CPU has 13 General Purpose 32-bit registers to work with.
  • Armv8 (e.g.,RPi4) actually has 31 64-bit registers.
  • r0, r1,... r12.
  • We use these registers to load in values, perform operations and write back out to memory
  • We also use them to pass arguments to functions (we’ll get to these later)

TURNING ON AN LED

BASE = $FE000000 ; $ means HEX
GPIO_OFFSET=$200000 You will notice a lot of

numbers being referred to

mov r0,BASE in this code.
orr r0,GPIO_OFFSET ;r0 now equals 0xFE200000

Lets look at some of these

mov r1,#1 and why they are there
lsl r1,#24 ;write 1 into r1, lsl 24 times to move the 1 to bit 24
str r1,[r0,#4] ;write it into 5th (16/4+1)block of function register

mov r1,#1
lsl r1,#18 ;write 1 into r1, lsl 18 times to move the 1 to bit 18
str r1,[r0,#28] ;write it into first block of pull-up register

loop$: b loop$;loop forever

TURNING ON AN LED

This is the “peripheral”

BASE = $FE000000 ; $ means HEX base address. This specific
GPIO_OFFSET=$200000 value represents the base

address of all registers on

mov r0,BASE the RPi 4 that interface
orr r0,GPIO_OFFSET ;r0 now equals 0xFE200000 with peripheral

components (eg the GPIO

mov r1,#1 pins)
lsl r1,#24 ;write 1 into r1, lsl 24 times to move the 1 to bit 24
str r1,[r0,#4] ;write it into 5th (16/4+1)block of function register

mov r1,#1
lsl r1,#18 ;write 1 into r1, lsl 18 times to move the 1 to bit 18
str r1,[r0,#28] ;write it into first block of pull-up register

loop$: b loop$;loop forever

TURNING ON AN LED

BASE = $FE000000 ; $ means HEX This is the offset from the
GPIO_OFFSET= $200000 base address that marks

mov r0,BASE the start of the GPIO
orr r0,GPIO_OFFSET ;r0 now equals 0xFE200000 registers (which we need

to read and write to/from

mov r1,#1 the GPIO pins).
lsl r1,#24 ;write 1 into r1, lsl 24 times to move the 1 to bit 24
str r1,[r0,#4] ;write it into 5th (16/4+1)block of function register

mov r1,#1
lsl r1,#18 ;write 1 into r1, lsl 18 times to move the 1 to bit 18
str r1,[r0,#28] ;write it into first block of pull-up register

loop$: b loop$;loop forever

TURNING ON AN LED

These two operations add

BASE = $FE000000 ; $ means HEX the GPIO OFFSET to the
GPIO_OFFSET= $200000 BASE address.

mov r0,BASE Mov moves the value
orr r0,GPIO_OFFSET ;r0 now equals 0xFE200000 referred to by BASE into

mov r1,#1 the register r0
lsl r1,#24 ;write 1 into r1, lsl 24 times to move the 1 to bit 24
str r1,[r0,#4] ;write it into 5th (16/4+1)block of function register orr has the effect of

adding GPIO_OFFSET to

mov r1,#1 the current contents of r0
lsl r1,#18 ;write 1 into r1, lsl 18 times to move the 1 to bit 18 (BASE).
str r1,[r0,#28] ;write it into first block of pull-up register
The result is stored in r0,

loop$: which now refers to the b loop$;loop forever base memory address of the GPIO registers

WHICH BASE ADDRESS FOR WHICH RPI

The peripheral base address depends on which model Pi you are using.

Notice however that the GPIO offset value is the same for all See https://github.com/FelipMarti/COS10004-RPi for more information on Pi model specifics

TURNING ON AN LED

BASE = $FE000000 ; $ means HEX
GPIO_OFFSET=$200000

What about these numbers?

mov r0,BASE
orr r0,GPIO_OFFSET ;r0 now equals 0xFE200000

Where did they come from

mov r1,#1 And what do they mean ?
lsl r1,#24 ;write 1 into r1, lsl 24 times to move the 1 to bit 24
str r1,[r0,#4] ;write it into 5th (16/4+1)block of function register These numbers all refer to

settings and programming of

mov r1,#1 the GPIO registers.
lsl r1,#18 ;write 1 into r1, lsl 18 times to move the 1 to bit 18
str r1,[r0,#28] ;write it into first block of pull-up register To understand this part of the

Code we need to understand loop$: what the GPIO chip is, and b loop$;loop forever how we interface with it to read to and write from the GPIO header pins.

SUMMARY

  • We have seen the structure of a simple Arm asm program
  • We have defined some operations:
  • Mov, orr, lsl, str, ldr, b
  • ARMv7 gives us 13 general purpose registers (r0- r12) to store values with
  • The peripheral base address refers to the start of the peripheral registers:
  • Pi model specific so you need to know which one is for you!
  • Next – the GPIO chip and how to program it!