Embedded System
Lecture 4: Introduction to ARM Assembly
Language Programming
Introduction to GNU ARM Tool
Chain
Prog1.s
.section .text
.global _start
_start:
MOV r0, #0x11 @ load initial value
MOV r1, r0, LSL #1 @ shift 1 bit left
MOV r2, r1, LSL #1 @ shift 1 bit left
loop:
B loop @ wait for result
.end
Assemble & Link
$ armelfas gstabs mcpu=arm7tdmi
prog1.s o prog.o
$ armelfld prog1.o o prog1.elf
$ armelfinsight prog1.elf
$ armelfobjdump D prog1.elf
$ armelfobjdump S prog1.elf
$ armelfobjdump t prog1.elf
$ armelfobjdump t prog1.o
Structure of Assembly Language
Program
General form of source lines in your assembly file is
{label} {instruction|directive|pseudoinstruction} {;comment}
For GNU ARM Assembly Prog
Label: instruction/directive/psedoinstruction @comment
●
All the sections within a source line (or statement) are optional.
●
Label is a name that represents an address in memory.
●
Labels must start at the beginning of the line
●
Labels do not start with a digit. However it can contain any alphabet, digits, and few
special characters (“_”, “.” and “$”).
●
Instruction/directive/pseudo-instruction must be preceded by a white space, either a tab
or any number of white spaces.
●
Comments are preceded by ;, @. C style commenting /* .. */ is also allowed
●
Constants
●
Decimal eg. 123
●
Hexadecimal eg. 0X3F
●
n_xxx (n is the base and xxx is the number)
●
Character constants: 'A' '\n'
●
String constants: “Hello World\n”
●
Housekeeping rules
●
Mnemonics can be written either in all small letters or in all capital
letters. While ADD or add is valid, Add is not valid.
●
Split up long lines using backslash (\) character. There must not
be any other characters following the backlash, such as space or
tab.
Assembler Directives
●
Directives are instructions to assembler to do something itself.
●
All assembler directives start with a period ('.').
●
.byte expression
Insert (8-bit) byte value of the expression into the object file.
.byte 64, 'A'
;insert byte 0x40,0x41
.byte 0x42
;insert byte 0x42
.byte 0b1000011,0104 ;insert bytes 0x43,0x44
●
.data: Switch the destination of following statements into the
data section of the final executable.
●
All executable programs have at least two sections called
.text
.text
and
.data
.data
●
.end
.end marks the end of source code file; everything after this
directive is ignored by the assembler.
●
.global symbol
.global symbol
specify that the symbol is to be made globally visible to all modules
(source code files) that are part of the executable, and visible to the GNU
linker. The symbol
_start
_start, which is required by the GNU Linker to
specify the first instruction to be executed in a program, must always be
a global one.
●
.text
.text
Switch the destination of the following statements into the text
section of the final executable. This is the section where assembly
instructions should be placed.
●
.section name [, “flags” [,@type]]
.section name [, “flags” [,@type]] (for ELF targets)
It instructs the assembler to create a new code or data section. Sections
are independent, named, indivisible chunk of code or data that are
manipulated by the linker.
●
.equ symbol, expression
.equ symbol, expression
This directive sets the value of symbol to expression.
●
.align abs_expr1 abs_expr2 abs_expr3
.align abs_expr1 abs_expr2 abs_expr3
●
Pad the location counter to a particular storage boundary.
●
abs_expr1: alignment required
abs_expr2: fill value to be stored in the padding bytes.
abs_expr3: max number of bytes to be skipped by this alignment
directive
●
All arguments are optional. If all arguments are missing .align inserts
zero to 3 bytes of 0x00 so that the next location will be on a 4-byte
(word) boundary.
.byte 0x55 ; inserts the byte 0x55
.align ; inserts three alignment bytes: 0x00 0x00
0x00
.word 0xAA55EE11 ; inserts the bytes 0x11 0xEE 0x55
0xAA (LSB order)
●
.space size, fill
.space size, fill
reserves a block of memory of size bytes each of value fill.
Macros
●
Macro definition allow a programmer to build definitions of functions or
operations once, and then call this operation by name throughout the
code, saving some writing time.
●
Macros can be a part of conditional assembly, wherein parts of the
source file may or may not be compiled based on certain variables.
●
Macro definitions are substituted at assembly time, replacing the
macro call with the actual assembly code.
●
Syntax:
.macro <macroname> {$cond} {$par1{,$par2}...}
.... code
.endm
.macro AddMul vara, varb, varc
.macro AddMul vara, varb, varc
ADD \vara, \varb, \varc @add two terms
ADD \vara, \vara, #6 @add 6 to the sum
MOV \vara, \vara, LSL #3 @multiply by 8
.endm
.endm
_start:
MOV r0, #10
MOV r1, #20
MOV r2, #30
AddMul r0, r1, r2
AddMul r0, r1, r2
loop:
b loop @wait here
.end
ARM Instruction Set
●
Data Processing Instructions
●
Branch Instructions (Flow Control)
●
Status Register transfer instructions (Logic/Bit
bashing)
●
Load and Store instructions (Memory Access)
●
Co-processor instructions (System Control)
●
Exception generating instructions (Priviledged)
Data Processing Instructions
●
Manipulate data within registers.
●
Move instructions, arithmetic instructions,
logical instructions, comparison instructions and
multiply instructions.
●
Most data processing instructions can process
one of their operands using the barrel shifter.
●
If you use the S suffix on a data processing
instruction, then it updates the flags in the
cpsr
cpsr.
Move Instructions
●
It copies N into a destination
register.
●
N could be register or an immediate
value.
Barrel Shifter
●
Data processing instructions are
processed within the ALU.
●
The 32-bit binary pattern in one of
the source registers can be shifted
left or right before it enters the ALU.
●
Some data processing instructions
do not use barrel shift. For example:
MUL, CLZ (count leading zeros),
QADD (signed saturated 32-bit add)
instructions.
●
Pre-processing or shift occurs within
the cycle time of the instruction.
●
MOV r7, r5, LSL #2
Arithmetic Instructions
●
Implement addition and subtraction of 32-bit signed and unsigned
values.
●
e.g. : SUB r0, r1, r2
●
A wide range of second operand shift is available for arithmetic and
logical instructions.
●
ADD r0, r1, r1, LSL #1 ; let r0 = 3 * r1
Logical Instructions
0
r0 = 0x00000000
r1 = 0x02040608
r2 = 0x10305070
ORR r0, r1, r2
r0 = 0x12345678
r0 = 0x00000000
r1 = 0x02040608
r2 = 0x10305070
ORR r0, r1, r2
r0 = 0x12345678
r1 = 0b1111
r2 = 0b0101
BIC r0, r1, r2
r0 = 0b1010
Comparison Instructions
●
Used to compare or test a register with 32-bit value.
●
It updates the cpsr flag bits according to the result, but do not
affect other registers.
●
After the bits have been set, the information can then be used
to change program flow by using conditional execution.
Multiply Instructions
●
Long multiply instructions (SMLAL, SMULL,
UMLAL, and UMULL) produce 64-bit result.
The result is placed in two 32-bit registers
labelled RdLo and RdHi.
Branch Instructions
●
A branch instruction is used to change the flow
of execution or is used to call a sub-routine.
●
This type of instruction allows programs to have
subroutines, if-then-else structures and loops.
●
The branch labels are placed at the beginning
of the line and are used to mark an address
that can be used later by the assembler to
calculate the branch offset.
Examples
Summary
●
Introduction to GNU ARM Tool Chain
●
Assembler Directives
●
Macros
●
Data Processing Instructions
●
Data Movement between registers
●
Arithmetic & Logical Operations
●
Multiply
●
Barrel Shifter