0% found this document useful (0 votes)
16 views40 pages

NET3001 2 Asm

NET3001-2-Asm

Uploaded by

werqt01
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
16 views40 pages

NET3001 2 Asm

NET3001-2-Asm

Uploaded by

werqt01
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 40

NET3001

Assembly Language
Sample Program

 task: add the contents of address 0x2000.0000 to


the contents of address 0x2000.0004 and store the
result in address 0x2000.0010
 plan
 load the number 0x2000.0000 into r7
 load the contents of 0x2000.0000 into r4
 load the contents of 0x2000.0004 into r5
 add the contents r5 to the r4
 store the result r4 into address 0x2000.0010
Sample Program

.text // we are creating program


.global main // visible outside the obj file
main: // a label to the symbol table
mov r7, #0x20000000 // this is a number

ldr r4,[r7] // read 0x2000.0000 into r4


ldr r5,[r7,#4] // read 0x2000.0004 into r5

add r4, r4, r5 // add

str r4,[r7,#0x10] //store it into 0x2000.0010


Assembly Directives

 cpu instructions create a flow of instructions at the


current location pointer

 assembler directives do not create code, but direct


the assembler to
 set a new location pointer
 create spaces in the flow
 set data strings into the flow
 add labels to the symbol table
Assembly Directives
 .text

Short form for .section .text
 the linker will put this at 0x0800.0000, after vectors
 .data

Short form for .section .data
 the linker will put this at 0x2000.0000
 .section .bss
 .section .vectors

the linker will put this at 0x0800.0000
 These all inform the assembler about where the subsequent
code/data is to go
 //
 /* ….. */
Labels
 Any word beginning in the left hand column and
ending with a colon is a label
 this causes an entry in the symbol table
 the value of this symbol is the value of the current location
counter

.text <- set location = 0x0000


main: mov r1, #0x600 <- create label “main”
mov r4, #0
loop1: mov r12, #5 <- create label “loop1”
add r4, r12, r4

.data <- set location = 0x2000.0000


.byte 14
<- location is now 0x2000.0001
2 step assembly

 the system we are using creates a program in two


steps
 assembler
 translates assembly instructions into binary opcodes
 does not finalize where to store them
 leaves the result in an object file
 linker
 binds one or more object files and assigns the code to
specific addresses
 creates an executable file (or loadable)
 the other steps are loading and debugging
Cross Assembler

 In this course, we are using a cross assembler


 we are using a Pentium/x86 processor to prepare the
code that will run on a Cortex processor
 Similarly, later in the course, we will be using a
cross compiler
Assembler Directives

 .byte d
 .word d
 .ascii “string”
 .asciz “string”
 .string “string”
 create bytes in the data stream

 NOTE: just like in C/C++, a single quote 'a' is


just a single character(char), but a double
quote “a” is a string (char[])
Assembler Directives

 .fill n,s,f
 fills n times s bytes with f (s=1,2 or 4)
 .space n,f
 .skip n,f
 fill n bytes with f
 .org n
 moves ahead by n bytes
Assembler Directives

 .equ
 .set
 add entries to the symbol table
 .
 if you use the symbol “.” it means the current location
counter
 this may come in hand in obscure situations
Assembly Instructions: Direction

 in the ARM and Cortex, all instructions operate from


right to left, except STR
 in other CPU's, this may be different
 i386 is often right to left, but not always
mov eax, #45
 in MSP430, instructions operate from left to right
mov #123, r12
Assembly Instructions: Vocabulary
 in the ARM/Cortex

data movement within the ALU is “move”

data movement to RAM/FLASH/IO is load or store
 mem-to-mem move is not possible
registers memory
 in other CPU's this may be different

i386: “move” is from reg/mem to reg/mem store
mov
 “in” is from i/o to reg
 “out” is from reg to i/o load
 Motorola
 “load” is from mem/io to reg (same as ARM)

“store” is from reg to mem/io (same as ARM) !! no
 “transfer” is from reg to reg mem-to-mem
 “move” is from mem/io to mem/io move
 in MSP430, all data movement is “move”
Data Movement

data(32)
store
load Flash/Program
CPU addr(32) addr
match
move

RAM/variables
addr
match

other
addr
Getting numbers into registers
you can use a mov instruction to put a “small” bit
pattern into a register
mov r4,#12
mov r5,#0x3A000000
but you can't use a mov for a complex pattern
mov r7,#0x20001c44 // <----not allowed

you have two choices:


 move it in chunks
mov r7,#0x20000000
orr r7,r7,#0x1c00 // r7=0x20001c00
orr r7,r7,#0x44 // r7=0x20001c44

or you can put the number nearby to your code, and do a ldr and
use the PC (r15) to fetch it
ldr r7,=0x20001c44
turns into
ldr r7,[r15,#some_distance_away]
A common idiom for addressing
One of the first things we have to do on the Cortex is
turn on the various parts of the chip.....in C
RCC->APB2ENR |= 0x44A3D;// enable zones a-d of gpio
// the left hand side is at address 0x4002.1018
but you can't use a mov for a complex pattern
mov r7,#0x40021018 // <----not allowed

Here's now it could be done:


movw r7,#0x40000000
orr r7,r7,#0x00021000 // r7=0x40021000
orr r7,r7,#0x18 // r7=0x40021018
movw r6,#0x4a3d
orr r6,r6,#0x00040000 // r6=0x00044a3d
str r6,[r7]

I don't recommend this style
 have a look at the next slide..........
A common idiom (cont'd)....literal mode
Another way to do the same task uses the '=' prefix
RCC->APB2ENR |= 0x44A3D;// enable zones a-d of gpio
// the left hand side is at address 0x4002.1018
can turn into
ldr r7,=0x40021018 // just add the = in front
ldr r6,=0x44a3d // remember this is a LDR
str r6,[r7]

what the assembler does:


ldr r7,[pc,#0x14]// reach ahead into flash
ldr r6,[pc,#0x18]
str r6,[r7]
// a gap
.word 0x40021018 // this area is called the pool
.word 0x000ffa3d
oddly, this is slightly slower code, but takes the least amount of
flash, and is much easier to understand
A common idiom (cont'd).....MOVT
Another third way to do the same task uses MOVT
RCC->APB2ENR |= 0x44A3D;// enable zones a-d of gpio
// the left hand side is at address 0x4002.1018
can turn into
movw r7,#0x1018 // fill in the bottom half
movt r7,#0x4002 // is “move into top”
movw r6,#0x4a3d // again, the bottom half
movt r6,#0x4 // “move into top” of r6
str r6,[r7]

in fact, this is the fastest version, but not quite so easy to


understand
Putting it all together

.text // we are creating program


.global main // visible outside the obj file
main: // a label to the symbol table
mov r7, #0x20000000
ldr r6, [r7] // read 0x2000.0000 into r6
ldr r5, [r7, #4] // read the next word into r5
add r6, r5, r6 // add them
str r6, [r7, #0x10] // store into the destination
Again, including the data

.text // we are creating program


.global main // visible outsidethe obj file
main: // a label to the symbol table
mov r7,#0x20000000
ldr r6, [r7]// read 0x2000.0000 into r6
ldr r5, [r7,#4] // read the other one into r5
add r6, r5, r6 // add
str r6, [r7,#0x10] // store into the destination

.data
.word 0x328321 // memory at 0x2000.0000
.word 0x434 // at 0x2000.0004
.org 0x10 // skip ahead to 0x2000.0010
.fill 2 // empty space for the answer
Again, using labels

.text // we are creating program


.global main // visible outside the obj file
main: // a label to the symbol table
ldr r7,=nStudentsOnTime
ldr r6,[r7] // r6 = nStudentsOnTime
ldr r5,[r7,#4] // r5 = nLatecomers
add r6, r5, r6 // r6 = r5 + r6
str r6,[r7,#0x10] // nTotalStudents = r6

.data
nStudentsOnTime: .word 12
nLatecomers: .word 4
.org 0x10 // skip ahead to 0x2000.0010
nTotalStudents: .fill 2
Symbol Table

 while the assembler is running, it collects all the


symbols into a symbol table
 this is just a spreadsheet with columns for
 name
 value
 type
 size
From the example

name value type size


main 0x0800.0008 label 0
nStudentsOnTime 0x2000.0000 word 4
nLatecomers 0x2000.0004 word 4
nTotalStudents 0x2000.0010 word 4
Example 2

 write a program to delay by 40,000 loops


Example 2

 write a program to delay by 40,000 loops


.text
.global delay40k
delay40k:
movw r5,#40000 // start with r5 set
s1: subs r5, r5, #1 // sub 1, set flags
bne s1 // if we're not done, loop
Example 3

 modify example 2 to take exactly 1msec


.text
.global delayMsec
delayMsec:
movw r5,#2667 //each loop takes .375usec
s1: subs r5, r5, #1 // sub 1
bne s1 // if we're not done, loop
Example 4

 delay loop, using global variable


.text
.global delaySome
delaySome:
ldr r7, =delayTime
ldr r6, [r7]
delayMsec:
movw r5,#2667 // each loop takes 0.375usec
s1: subs r5, r5, #1 // sub 1
bne s1 // if we're not done, loop

subs r6, r6, #1


bne delayMsec

.data
delayTime: .word 5 // the msec to delay
Symbol Table

Name Value Type


delaySome x (maybe 0x0800.0008) label
delayMsec x+6 label
s1 x+10 label
delayTime y (maybe 0x2000.0000) short

●the symbol table here shows how it might


look after the assembler, but before the linker
Example 5
 write a snippet which does a checksum on a string
of bytes
 the address of the string is in a variable
 the string count is in a variable
 and the string data is in another variable

put the checksum into a 4th variable

char* stringAddr = myString;


char csum = 0;
for (i=stringCount; i>0; i--) {
csum += *stringAddr;
stringAddr++; }
Example 5
.data
myString: .ascii “5411003412990475” // credit card
stringCount: .word 16
csum: .fill 1

.text
.global calcCheckSum
.type calcCheckSum,%function
calcCheckSum:
ldr r11, =myString
ldr r10, =stringCount
ldr r12,[r10] // go to ram to get length
mov r6, #0 // this will accumulate
cs1:
ldrb r4,[r11] // fetch and add to csum
add r6, r4
add r11, #1 // point to next char
subs r12, #1 // decrement & test
bne cs1
ldr r10, =csum // and save the answer
strb r6, [r10]
Symbol Table Example 5

Name Value Type Size Content


calcCheckSum x label;func 0 n/a
cs1 x+0x0C label 0 n/a
myString y byte[] 16 5411.....
stringCount y+0x10 word 4 16=0x10
csum y+0x14 byte 1 the answer

●this symbol table shows how it might look after the assembler
●the assembler builds the opcodes, but leaves empty spots where
the operands will go; the linker fills in the blanks from the symbol
table
Symbol Table Example 5

Name Value Type Size Content


calcCheckSum 0x0800.0008 label;func 0 n/a
cs1 0x0800.0014 label 0 n/a
myString 0x2000.0000 byte[] 16 5411.....
stringCount 0x2000.0010 word 4 16=0x10
csum 0x2000.0014 byte 1 the answer

●the addresses above show how the symbol table might look after
the linker has finished; this example assumes there is no other
code/data in the project
●the address for calcCheckSum will get changed to 0x0800.0009

when it use stored as a word; that's what the %function operator


does; remember that we're in a Thumb environment, and any LDR
to r15 must be an odd number
Branching

 you can direct the flow of instructions by branchs, which are


instructions which modify r15, the program counter
 with the jump instructions, the offset is included in the opcode
 the bottom 11 bits, a signed offset
 since the PC is always even, the offset is doubled before use
 add it to the PC, which is the already incremented, 4 larger
than the address of the instruction
 dont' worry: the assembler does all the math for you

branch offset in words


opcode (offset in bytes/2)
Instruction Take Time
 each instruction takes a certain number of CPU cycles
 the boards we will use operate at 8 million cycles per second
 register-to-register operations take 1
 jumps take 2
 loads and stores use 2
 if you push or pop n registers, it takes n+1 cycles
mov r3, r3 takes 1
ldr r7, [r3] takes 2
push {r4, r5, r6} takes 4
Binary Math
 shift left by 1
 same as multiply by 2
 0x14 (2010) << 1 → 0x28 (40 10)
 shift left by 4
 multiply by 16
 0x14 (2010) << 4 → 0x140 (32010)
 shift right by 1
 divide by 2
 0x14 (2010) >> 1 → 0x0A (1010)
 if it ends with a 1, it's odd

1,3,5,7,9,b,d,f
 0x21 = 0b0010.0001 = 33 10
 if it start with a 1, it's negative
 0xFFFF.FFD1 = -47 10
Binary Math

 2's complement
 flip all the bits and add 1
 memorize these
0xFFFF.FFFF = -1
...FE = -2
...FD = -3
...FC = -4
...F0 = -16
 and these while you're at it
0xA = 10 0xD = 13 0x14 = 20
0xB = 11 0xE = 14 0x1E = 30
0xC = 12 0xF = 15 0x50 = 80
Binary Math
unsigned signedhex number line unsigned
signed
82 82 52
103 103 67
185 -71 V B9 -128 0 127 255

82 82 52
202 -54 CA
28 C 28 1C -128 0 127 255

189 -67 BD
12 12 0C
-128 0 127 255
201 -55 C9
189 -67 BD
221 -35 DD -128 0 127 255
154 C -102 9A
189 -67 BD
133 -123 85 -128 0 127 255

66 C 66 V 42
Unsigned/Signed Math
 two small numbers  small +ve, small +ve
4,660=0x1234
4,660=0x1234 22,136=0x5678
30,328=0x7678 26,796=0x68AC

big +ve, big +ve
34,988=0x88AC 4,660=0x1234

two large numbers 30,328=0x7678
34,988=0x88AC
35,243=0x89AB 
small -ve, small -ve
52,719=0xCDEF -292=0xFEDC
87,962=0x1579A -12,817=0xCDEF
-13,109=0x1CCCB
 two very large numbers 
big -ve, big -ve
65,244=0xFEDC -30,293=0x89ab
-12,817=0xCDEF
52,719=0xCDEF -43,110=0x1579A
117,963=0x1CCCB 
small +ve, small -ve
4,660=0x1234
-12,817=0xCDEF
-8,157=0xE023
Why do we use 2's complement?
 1's complement

just flip the bits
-2 0xFD
-1 0xFE
0 0 or 0xFF (either)
1 0x01
….
 suppose we do a few math calculations

-2 + 3 → 0xFD + 0x03 = 0x01
 but if we treat 0xFD as unsigned (253)...

then 0xFD+0x03 = 0x02 (with carry)


 -3 + -3 → 0xFC + 0xFC = 0xF9

but if we treat 0xFC as unsigned (252)
then 0xFC+0xFC = 0xF8 (with carry)
 we would need a different “adder” for signed &
unsigned
Why do we use 2's complement?
 2's complement
 flip the bits and add one
-2 0xFE ← even number
-1 0xFF ← odd number
0 0
1 0x01
….
 suppose we do a few math calculations

-2 + 3 → 0xFE + 0x03 = 0x01
 but if we treat 0xFE as unsigned (254)...

then 0xFE+0x03 = 0x01 (with carry)


 -3 + -3 → 0xFD + 0xFD = 0xFA

but if we treat 0xFD as unsigned (253)
then 0xFD+0xFD = 0xFA (with carry)
 we can use the same “adder” for signed & unsigned
 we just need different overflow conditions: C & V

You might also like