Module-2 Notes PDF
Module-2 Notes PDF
Module-2 Notes PDF
Assembly basics:
Registers
The Cortex™-M3 processor has registers R0 through R15 and a number of special registers. R0
through R12 are general purpose, but some of the 16-bit Thumb® instructions can only access
R0 through R7 (low registers), whereas 32-bit Thumb-2 instructions can access all these
registers. Special registers have predefined functions and can only be accessed by special register
access instructions.
General Purpose Registers R0 through R7
The R0 through R7 general purpose registers are also called low registers. They can be accessed
by all 16-bit Thumb instructions and all 32-bit Thumb-2 instructions. They are all 32 bits; the
reset value is unpredictable.
General Purpose Registers R8 through R12
The R8 through R12 registers are also called high registers. They are accessible by all Thumb-2
Instructions but not by all 16-bit Thumb instructions. These registers are all 32 bits; the reset
value is unpredictable.
The text after each semicolon (;) is a comment. These comments do not affect the program
operation, but they can make programs easier for humans to understand.
One of the most basic functions in a processor is transfer of data. In the Cortex-M3, data
transfers can be of one of the following types:
• Moving data between register and register
• Moving data between memory and register
• Moving data between special register and register
• Moving an immediate data value into a register
The command to move data between registers is MOV (move). For example, moving data from
register R3 to register R8 looks like this:
MOV R8, R3
Another instruction can generate the negative value of the original data; it is called MVN (move
negative).
The basic instructions for accessing memory are Load and Store.
Load (LDR) :transfers data from memory to registers, and Store transfers data from registers to memory.
The exclamation mark (!) in the instruction specifies whether the register Rd should be updated
after the instruction is completed.
For example, if R8 equals 0x8000:
STMIA.W R8!, {R0-R3} ; R8 changed to 0x8010 after store; (increment by 4 words)
ARM processors also support memory accesses with preindexing and postindexing. For
preindexing, the register holding the memory address is adjusted. The memory transfer then
takes place with the updated address. For example,
LDR.W R0,[R1, #offset]! ; Read memory[R1+offset], with R1
; update to R1+offset
Two other types of memory operation are stack PUSH and stack POP. For example,
PUSH {R0, R4-R7, R9} ; Push R0, R4, R5, R6, R7, R9 into stack memory
In this case, instead of popping the LR register back and then branching to the address in LR, we
POP the address value directly in the program counter. The Cortex-M3 has a number of special
registers.
To access these registers, we use the instructions MRS and MSR.
For example,
access a peripheral register, so you need to put the address value into a register beforehand. For
small values (8 bits or less), you can use MOVS (move).
For example,
MOVS R0, #0x12 ; Set R0 to 0x12
For a larger value (over 8 bits), you might need to use a Thumb-2 move instruction. For example,
MOVW.W R0, #0x789A ; Set R0 to 0x789A
Or if the value is 32-bit, you can use two instructions to set the upper and lower halves:
MOVW.W R0,#0x789A ; Set R0 lower half to 0x789A
MOVT.W R0,#0x3456 ; Set R0 upper half to 0x3456.Now R0=0x3456789A
The Cortex-M3 provides many different instructions for data processing. A few basic ones are
Introduced here. Many data operation instructions can have multiple instruction formats. For
example,an ADD instruction can operate between two registers or between one register and an
immediate data value:
ADD R0, R0, R1 ; R0 = R0 + R1
ADDS R0, R0, #0x12 ; R0 = R0 + 0x12
ADD.W R0, R1, R2 ; R0 = R1 + R2
These are all ADD instructions, but they have different syntaxes and binary coding. With the
traditional Thumb instruction syntax, when 16-bit Thumb code is used, an ADD instruction can
change the flags in the PSR. However, 32-bit Thumb-2 code can either change a flag or keep it
unchanged. To separate the two different operations, the S suffix should be used if the following
operation depends on the flags:
ADD.W R0, R1, R2 ; Flag unchanged
ADDS.W R0, R1, R2 ; Flag change
The compare (CMP) instruction subtracts two values and updates the flags (just like SUBS), but
the result is not stored in any registers. CMP can have the following formats:
CMP R0, R1 ; Calculate R0 – R1 and update flag
CMP R0, #0x12 ; Calculate R0 – 0x12 and update flag
A similar instruction is the CMN (compare negative). It compares one value to the negative
(two’s complement) of a second value; the flags are updated, but the result is not stored in any
registers:
CMN R0, R1 ; Calculate R0 – (-R1) and update flag
CMN R0, #0x12 ; Calculate R0 – (-0x12) and update flag
The TST (test) instruction is more like the AND instruction. It ANDs two values and updates the
flags. However, the result is not stored in any register. Similarly to CMP, it has two input
formats:
The usage of CBNZ is similar to CBZ, apart from the fact that the branch is taken if the Z flag is
not set (result is not zero). For example,
status = strchr(email_address, '@');
if (status == 0){//status is 0 if @ is not in email_address
show_error_message();
exit(1);
}
Various software programs are available for developing Cortex-M3 applications. The concepts of
code Generation flow in terms of these tools are similar. For the most basic uses, you will need
assembler, a C compiler, a linker, and binary file generation utilities.