Using Labels as an Address to Read From in Thumb Assembly
Joseph Yiu , in The Definitive Guide to ARM® CORTEX®-M3 and CORTEX®-M4 Processors (Third Edition), 2014
5.6.2 Retentivity access instructions
There are large numbers of memory access instructions in the Cortex®-M3 and Cortex-M4 processors. This is due to the combination of support of various addressing modes, besides as data size and data transfer direction. For normal data transfers, the instructions bachelor are given in Table 5.6
Data Type | Load (Read from Retention) | Store (Write to Retentivity) |
---|---|---|
eight-bit unsigned | LDRB | STRB |
8-fleck signed | LDRSB | STRB |
sixteen-bit unsigned | LDRH | STRH |
xvi-fleck signed | LDRSH | STRH |
32-fleck | LDR | STR |
Multiple 32-bit | LDM | STM |
Double-word (64-bit) | LDRD | STRD |
Stack operations (32-bit) | POP | Push |
Notation: The LDRSB and the LDRSH automatically perform a sign extend performance on the loaded data to convert it to a signed 32-bit value. For instance, if 0x83 is read in a LDRB instruction, the value is converted into 0xFFFFFF83 before being placed in the destination register.
If the floating point unit is nowadays, the instructions in Table 5.7 are besides available to transfer information between the register bank in the floating indicate unit of measurement and memory.
Data Type | Read from Memory (Load) | Write to Memory (Shop) |
---|---|---|
Single-precision data (32-bit) | VLDR.32 | VSTR.32 |
Double-precision data (64-bit) | VLDR.64 | VSTR.64 |
Multiple data | VLDM | VSTM |
Stack operations | VPOP | VPUSH |
There are besides a number of addressing modes available. In some of these modes, you can also optionally update the register belongings the address (write dorsum).
Immediate offset (pre-index)
The memory address of the data transfer is the sum of a annals value and an immediate constant value (outset). Sometimes this is referred to as "pre-index" addressing. For example:
LDRB R0, [R1, #0x3] ; Read a byte value from address R1+0x3, and store the read information in R0.
The offset value can exist positive or negative. Table v.8 shows a listing of commonly used load and store instructions.
Example of Pre-alphabetize Accesses Note: the #offset field is optional | Clarification |
---|---|
LDRB Rd, [Rn, #offset] | Read byte from retentiveness location Rn + commencement |
LDRSB Rd, [Rn, #offset] | Read and signed extend byte from retentiveness location Rn + commencement |
LDRH Rd, [Rn, #offset] | Read half-word from memory location Rn + beginning |
LDRSH Rd, [Rn, #first] | Read and signed extended half-word from retentiveness location Rn + offset |
LDR Rd, [Rn, #offset] | Read word from memory location Rn + offset |
LDRD Rd1,Rd2, [Rn, #offset] | Read double-word from memory location Rn + get-go |
STRB Rd, [Rn, #showtime] | Store byte to retention location Rn + starting time |
STRH Rd, [Rn, #starting time] | Store half-word to memory location Rn + start |
STR Rd, [Rn, #starting time] | Shop discussion to memory location Rn + offset |
STRD Rd1,Rd2, [Rn, #offset] | Shop double-word to retentiveness location Rn + offset |
This addressing mode supports write dorsum of the annals belongings the address. For example:
LDR R0, [R1, #0x8]! ; Later the access to memory[R1+0x8], R1 is updated to R1+0x8
The exclamation marker (!) in the educational activity specifies whether the register holding the address should exist updated (write back) when the teaching is completed. The address used for the data transfer uses the sum of R1+0x8 calculated regardless of whether the exclamation mark (!) is stated. The write back operation tin can be used with a number of load and store instructions every bit shown in Tabular array 5.9.
Example of Pre-index with Write Back Note: the #offset field is optional | Clarification |
---|---|
LDRBRd, [Rn, #first]! | Read byte with write back |
LDRSB Rd, [Rn, #offset]! | Read and signed extend byte with write back |
LDRHRd, [Rn, #start]! | Read one-half-word with write back |
LDRSH Rd, [Rn, #commencement]! | Read and signed extended half-word with write dorsum |
LDRRd, [Rn, #offset]! | Read word with write back |
LDRDRd1,Rd2, [Rn, #kickoff]! | Read double-word with write back |
STRBRd, [Rn, #start]! | Store byte to retentivity with write back |
STRHRd, [Rn, #offset]! | Store half-give-and-take to retentiveness with write dorsum |
STRRd, [Rn, #offset]! | Store word to memory with write back |
STRDRd1,Rd2, [Rn, #offset]! | Shop double-word to retention with write back |
Please note that some of these instructions cannot be used with R15(PC) or R13(SP). In addition, the 16-bit versions of these instructions only back up low registers (R0-R7) and do not provide write back.
If the floating point unit is nowadays, the instructions in Table v.10 are as well available to perform LDR and STR operations to the registers in the floating point unit.
Examples Note: the #commencement field is optional | Description |
---|---|
VLDR.32Sd, [Rn, #offset] | Read unmarried-precision data from memory to unmarried-precision register Sd |
VLDR.64Dd, [Rn, #offset] | Read double-precision data from memory to double-precision register Dd |
VSTR.32Sd, [Rn, #offset] | Write single-precision data from single-precision register Sd to memory |
VSTR.64Dd, [Rn, #kickoff] | Write double-precision data from double precision annals Dd to memory |
Notation that many floating indicate instructions utilise the .32 and .64 suffixes to specify the floating information blazon. In almost toolchains, the .32 and .64 suffixes are optional.
PC-related addressing (Literal)
A memory access tin generate the address value from the current PC value and an offset value (Table five.11 ). This is commonly needed for loading immediate values into a register, likewise known every bit literal pool accesses, equally mentioned earlier in this chapter (LDR pseudo educational activity).
Example of Literal Read | Description |
---|---|
LDRBRt,[PC, #offset] | Load unsigned byte into Rt using PC outset |
LDRSB Rt,[PC, #offset] | Load and signed extend a byte data into Rt using PC offset |
LDRHRt,[PC, #first] | Load unsigned one-half-word into Rt using PC offset |
LDRSH Rt,[PC, #offset] | Load and signed extend a half-word data into Rt using PC get-go |
LDRRt, [PC, #beginning] | Load a word data into Rt using PC get-go |
LDRD Rt,Rt2,[PC, #offset] | Load a double-word into Rt and Rt2 using PC offset |
If the floating betoken unit is present, the instructions in Table 5.12 are too available.
Example of Literal Read | Clarification |
---|---|
VLDR.32 Sd,[PC, #outset] | Load single-precision information into single-precision annals Sd using PC first |
VLDR.64 Dd,[PC, #commencement] | Load double-precision information into double-precision register Dd using PC showtime |
Register offset (pre-index)
Another useful address style is the register offset. This is often used in the processing of data arrays where the address is a combination of a base address and an offset calculated from an alphabetize value. To make this address adding even more efficient, the index value can be shifted by a distance of 0 to three bits before being added to the base annals. For example:
LDR R3, [R0, R2, LSL #2] ; Read memory[R0+(R2 << ii)] into R3
The shift functioning is optional. You can have a simple operation like
STR R5, [R0,R7] ; Write R5 into retentivity[R0+R7]
Similarly to immediate showtime, there are various forms for unlike data size, as shown in Table five.xiii.
Instance of Annals Offset Accesses | Description |
---|---|
LDRBRd, [Rn, Rm{, LSL #n}] | Read byte from memory location Rn + (Rm << northward) |
LDRSB Rd, [Rn, Rm{, LSL #north}] | Read and signed extend byte from retentiveness location Rn + (Rm << due north) |
LDRHRd, [Rn, Rm{, LSL #north}] | Read half-word from memory location Rn + (Rm << due north) |
LDRSH Rd, [Rn, Rm{, LSL #due north}] | Read and signed extended half-word from retentiveness location Rn + (Rm << n) |
LDRRd, [Rn, Rm{, LSL #n}] | Read word from retention location Rn + (Rm << n) |
STRBRd, [Rn, Rm{, LSL #n}] | Store byte to retention location Rn + (Rm << n) |
STRHRd, [Rn, Rm{, LSL #northward}] | Store half-give-and-take to retentiveness location Rn + (Rm << n) |
STRRd, [Rn, Rm{, LSL #n}] | Store word to memory location Rn + (Rm << northward) |
Post-index
Retention access instructions with mail-index addressing mode also take an immediate offset value. However, the starting time is not used during the memory admission, just is used to update the address register after the data transfer is completed. For case:
LDR R0, [R1], #offset ; Read retentiveness[R1], then R1 updated to R1+offset
When the post-index memory addressing fashion is used, there is no demand to apply the assertion mark (!) sign because the base of operations address register is always updated if the information transfer is completed successfully. Tabular array 5.fourteen lists various form of mail indexing memory access instructions.
Example of Post Index Accesses | Description |
---|---|
LDRB Rd,[Rn], #get-go | Read byte from retentiveness[Rn] to Rd, then update Rn to Rn+commencement |
LDRSB Rd,[Rn], #offset | Read and signed extended byte from memory[Rn] to Rd, then update Rn to Rn+offset |
LDRH Rd,[Rn], #offset | Read half-give-and-take from memory[Rn] to Rd, then update Rn to Rn+starting time |
LDRSH Rd,[Rn], #first | Read and signed extended half-give-and-take from memory[Rn] to Rd, then update Rn to Rn+get-go |
LDR Rd,[Rn], #offset | Read word from memory[Rn] to Rd, then update Rn to Rn+offset |
LDRD Rd1,Rd2,[Rn], #offset | Read double-word from retentivity[Rn] to Rd1, Rd2, then update Rn to Rn+showtime |
STRB Rd,[Rn], #first | Store byte to memory[Rn] so update Rn to Rn+offset |
STRH Rd,[Rn], #beginning | Shop half-word to memory[Rn] then update Rn to Rn+offset |
STR Rd,[Rn], #showtime | Store word to memory[Rn] so update Rn to Rn+offset |
STRD Rd1,Rd2,[Rn], #offset | Shop double-word to memory[Rn] then update Rn to Rn+offset |
The post-index address mode can be very useful for processing data in an array. As shortly as an element in the array is accessed, the address register tin be adjusted to the side by side chemical element automatically to save code size and execution time.
Delight note that post-alphabetize instructions cannot be used with R15(PC) o R14(SP). The post-index memory access instructions are 32-flake. The outset value can be positive or negative.
Multiple load and multiple shop
Ane of the primal advantages of the ARM architecture is that it allows you lot to read or write multiple data that are contiguous in memory. The LDM (Load Multiple registers) and STM (Store Multiple registers) instructions merely support 32-bit information. They support two types of pre-indexing:
- •
-
IA: Increment address After each read/write
- •
-
DB: Decrement accost Before each read/write
The LDM and STM instructions can be used without base address write dorsum (Table 5.fifteen).
Examples of Multiple Load/Store | Description |
---|---|
LDMIA Rn,<reg list> | Read multiple words from memory location specified by Rn. Address Increment Later (IA) each read. |
LDMDB Rn,<reg list> | Read multiple words from memory location specified by Rn. Accost Decrement Earlier (DB) each read. |
STMIA Rn,<reg list> | Write multiple words to memory location specified by Rn. Address increment after each write. |
STMDB Rn,<reg listing> | Write multiple words to retentiveness location specified past Rn. Address Decrement Earlier each write. |
The <reg listing> in Table 5.15 is the annals list. It contains at to the lowest degree one register, and:
- •
-
Kickoff with "{" and cease with "}"
- •
-
Employ "-" (hypen) to indicate range. For example, R0-R4 means R0, R1, R2, R3 and R4.
- •
-
Utilise "," (comma) to divide each annals
For instance, the post-obit instructions read address 0x20000000 to 0x2000000F (iv words) into R0 to R3:
LDR R4,=0x20000000 ; Fix R4 to 0x20000000 (address)
LDMIA R4, {R0-R3} ; Read 4 words and store them to R0 - R3
The register listing tin can be non-contiguous such as {R1, R3, R5-R7, R9, R11-12}, which contains R1, R3, R5, R6, R7, R8, R11, R12.
Like to other load/store instructions, you can use write dorsum with STM and LDM. For instance:
LDR R8,=0x8000 ; Set R8 to 0x8000 (address)
STMIA R8!, {R0-R3} ; R8 change to 0x8010 after the store
Example of Multiple Load / Store with Write Back | Description |
---|---|
LDMIA Rn!,<reg list> | Read multiple words from memory location specified by Rd. Address Increase After (IA) each read. Rn writes back afterwards the transfer is washed. |
LDMDB Rn!,<reg list> | Read multiple words from memory location specified by Rd. Accost Decrement Before (DB) each read. Rn writes back after the transfer is done. |
STMIA Rn!,<reg list> | Write multiple words to retention location specified by Rd. Address increase after each write. Rn writes back after the transfer is done. |
STMDB Rn!,<reg list> | Write multiple words to memory location specified past Rd. Address Decrement Before each write Rn writes back later on the transfer is done. |
Instructions with multiple Load/Shop retention access instructions with write back are listed in Table 5.16. The 16-fleck versions of the LDM and STM instructions are limited to low registers simply and e'er have write back enabled, except when the base annals is one of the destination registers to be updated past the retentivity read.
If the floating indicate unit is present, the instructions in Table 5.17 are likewise available to perform load multiple and store multiple operations to the registers in the floating point unit.
Example of Multiple Load / Store with Write Back | Description |
---|---|
VLDMIA.32 Rn, <s_reg list> | Read multiple single-precision data. Address Increment After (IA) each read. |
VLDMDB.32 Rn, <s_reg list> | Read multiple unmarried-precision data. Address Decrement Before (DB) each read. |
VLDMIA.64 Rn, <d_reg list> | Read multiple double-precision information. Address Increase Afterwards (IA) each read. |
VLDMDB.64 Rn, <d_reg list> | Read multiple double-precision data. Accost Decrement Earlier (DB) each read. |
VSTMIA.32 Rn, <s_reg list> | Write multiple single-precision data. Address increment after each write. |
VSTMDB.32 Rn, <s_reg list> | Write multiple single-precision information. Address decrement before each write. |
VSTMIA.64 Rn, <d_reg list> | Write multiple double-precision information. Accost increment afterwards each write. |
VSTMDB.64 Rn, <d_reg list> | Write multiple double-precision data. Accost decrement before each write. |
VLDMIA.32 Rn!, <s_reg listing> | Read multiple unmarried-precision data. Address Increment After (IA) each read. Rn writes dorsum later on the transfer is done. |
VLDMDB.32 Rn!, <s_reg list> | Read multiple single-precision data. Address Decrement Earlier (DB) each read. Rn writes dorsum after the transfer is washed. |
VLDMIA.64 Rn!, <d_reg list> | Read multiple double-precision data. Address Increment After (IA) each read. Rn writes dorsum afterward the transfer is washed. |
VLDMDB.64 Rn!, <d_reg listing> | Read multiple double-precision data. Address Decrement Before (DB) each read. Rn writes back after the transfer is done. |
VSTMIA.32 Rn!, <s_reg listing> | Write multiple single-precision information. Address increment after each write. Rn writes back after the transfer is done. |
VSTMDB.32 Rn!, <s_reg list> | Write multiple single-precision data. Address decrement earlier each write. Rn writes dorsum after the transfer is washed. |
VSTMIA.64 Rn!, <d_reg list> | Write multiple double-precision data. Address increment after each write. Rn writes back after the transfer is washed. |
VSTMDB.64 Rn!, <d_reg list> | Write multiple double-precision information. Address decrement before each write. Rn writes dorsum later on the transfer is done. |
Stack button and pop
Stack push and pop are another grade of the shop multiple and load multiple. They use the currently selected stack pointer for address generation. The currently selected stack pointer tin can either be the Main Stack Pointer (MSP), or the Process Stack Pointer (PSP), depending on the current mode of the processor and the value in the CONTROL special annals (come across Chapter 4). Instructions for stack button and stack popular are shown in Tabular array v.18.
Example of Stack Operations | Description |
---|---|
Push button <reg listing> | Store register(s) in stack. |
POP <reg list> | Restore register(s) from stack. |
The register listing syntax is the same as LDM and STM. For instance:
PUSH {R0, R4-R7, R9} ; Push button R0, R4, R5, R6, R7, R9 into stack
POP {R2, R3} ; Popular R2 and R3 from stack
Usually a Button education volition have a corresponding POP with the aforementioned annals list, but this is not always necessary. For example, a common exception is when Pop is used as a function render:
Push button {R4–R6, LR} ; Save R4 to R6 and LR (Link Annals) at the
; beginning of a subroutine. LR contains the
; return address
… ; processing in the subroutine
Popular {R4-R6, PC} ; Pop R4 to R6, and return address from stack.
; the return address is stores into PC straight,
; this triggers a branch (subroutine return)
Instead of popping the render address into LR, and and then writing it to the program counter (PC), we can write the render address direct to PC to salve instruction count and cycle count.
The 16-chip versions of PUSH and Pop are limited to low registers (R0 to R7), LR (for PUSH), and PC (for Popular). Therefore if a loftier register is modified in a function and the contents of the register need to be saved, you lot need to apply a pair of 32-bit PUSH and Pop instructions.
If the floating indicate unit of measurement is present, the instructions in Tabular array 5.19 are also available to perform stack operations to the registers in the floating signal unit.
Example of Stack Operations | Description |
---|---|
VPUSH.32 <s_reg listing> | Store single-precision annals(due south) in stack. (i.eastward., s0-s31) |
VPUSH.64 <d_reg list> | Store double-precision annals(s) in stack. (i.e., d0-d15) |
VPOP.32 <s_reg list> | Restore unmarried-precision annals(s) from stack. |
VPOP.64 <d_reg listing> | Restore double-precision register(s) from stack. |
Different PUSH and POP, VPUSH and VPOP instructions require that:
- •
-
The registers in the annals listing are sequent
- •
-
The maximum number of registers stacked/unstacked for each VPUSH or VPOP is 16
If it is necessary to save more sixteen single-precision floating point registers, yous can utilize double-precision teaching, or use two pairs of VPUSH and VPOP.
SP-relative addressing
Also being used for the temporary storage of registers in functions or subroutines, the stack retentiveness is very oftentimes also used for local variables, and accessing these variables requires SP-relative addressing. In that location is no special 32-fleck version of SP-relative addressing as this is already covered by the load and shop instructions with immediate start. However, most 16-bit Thumb instructions can only use low registers. As a result, there is a pair of defended 16-bit version of LDR and STR instructions with SP-relative addressing.
An case of using SP-relative addressing fashion (Effigy 5.five) tin be: at the beginning of a part the SP value can be decremented to reserve space for local variables and and then the local variables tin can be accessed using SP-related addressing. At the end of the function, the SP is incremented to return to the original value, which frees the allocated stack space earlier returning to the calling code.
Load and store with unprivileged admission level
At that place is a gear up of load and store instructions to permit program code executing in privileged admission level to access retention with unprivileged access rights, as shown in Table five.xx.
Example of LDR/STR with Unprivileged Access Level | Clarification Annotation: the #get-go field is optional |
---|---|
LDRBT Rd, [Rn, #offset] | Read byte from retention location Rn + offset |
LDRSBT Rd, [Rn, #offset] | Read and signed extend byte from retentiveness location Rn + offset |
LDRHT Rd, [Rn, #offset] | Read half discussion from memory location Rn + commencement |
LDRSHT Rd, [Rn, #offset] | Read and signed extended one-half word from retention location Rn + showtime |
LDRT Rd, [Rn, #offset] | Read give-and-take from memory location Rn + outset |
STRBT Rd, [Rn, #offset] | Store byte to memory location Rn + starting time |
STRHT Rd, [Rn, #start] | Shop half-discussion to memory location Rn + outset |
STRT Rd, [Rn, #beginning] | Store word to memory location Rn + offset |
These instructions might be needed in some OS environments where an unprivileged application can access an API function (running within the privileged access level) with a data pointer as an input parameter, and this API operates on memory information specified by the arrow. If the information access is carried out using normal load and store instructions, the unprivileged awarding task will then have the power to alter information that is used by other tasks or Os kernel using this API. By coding the API using these special Load and Store instructions with unprivileged access level, the API tin can only access the data which the application task can access.
Sectional accesses
The exclusive access instructions are a special group of retentiveness access instructions for implementing semaphores or MUTEX (Mutual Exclusive) operations. They are normally used within embedded OS where a resource (frequently hardware, merely tin also be software) has to be shared betwixt multiple awarding tasks, or fifty-fifty multiple processors.
Sectional admission instructions include exclusive loads and exclusive stores. Special hardware inside the processor and optionally in the autobus interconnect are needed to monitor exclusive accesses. Inside the processor, a single bit register is present to record an on-going sectional access sequence: we phone call it the local exclusive access monitor. On the system bus level, an sectional admission monitor might also exist present to check if a retention location (or memory device) used by an exclusive access sequence has been accessed by some other processor or coach main. The processor has extra signals in the bus interface to indicate that a transfer is an exclusive admission and to receive a response from the organisation bus level sectional access monitor.
In a semaphore or a MUTEX operation, a data variable in RAM is used to represent a token. It can be used to indicate, for example, that a hardware resource has been allocated to an application task. For instance, presume that if the variable is 0, it indicates the resource is available, and 1 indicates that it is already allocated to a chore. The exclusive access sequence for requesting the resources might be:
- one.
-
The variable is accessed with an exclusive load (read). The local exclusive access monitor inside the processor is updated to indicate an active sectional access transfer and, if a motorbus level exclusive access monitor is present, information technology will also exist updated.
- 2.
-
The variable is checked past the application code to determine whether the hardware resource has already been allocated. If the value is 1 (already allocated), and then information technology can retry later or give upward. If the value is 0 (resource free), then it can try to allocate the resources in the adjacent step.
- three.
-
The task uses an exclusive store to write a value of ane to the variable. If the local exclusive access monitor is prepare and there is no error reported by the motorcoach level exclusive access monitor, the variable volition exist updated and the sectional store will get a success return condition. If something happened between the sectional load and sectional shop that could affect the exclusiveness of the access to the variable, the exclusive store will get a failed return status and the variable volition not be updated (either cancelled by the processor itself or the store is blocked by the charabanc level sectional access monitor).
- 4.
-
From the return status, the application task knows that if information technology has allocated the hardware resources successfully. If not, it tin can retry later or give up.
The exclusive shop fails if:
- •
-
The bus level sectional admission monitor returns an sectional neglect response (eastward.1000., the memory location or memory range has been accessed past some other processor)
- •
-
The local exclusive access monitor is not gear up. This can be acquired past:
- a)
-
Incorrect exclusive access sequence
- b)
-
An interrupt entry/go out between the exclusive load and exclusive store (the retention location or memory range could have been accessed by an interrupt handler or another application task).
- c)
-
Execution of a special educational activity CLREX that clears the local sectional access monitor.
The instructions for exclusive accesses are given in Table 5.21.
Instance of Exclusive Admission | Description |
---|---|
LDREXB Rt, [Rn] | Sectional read byte from retentiveness location Rn |
LDREXH Rt, [Rn] | Sectional read half-word from retentivity location Rn |
LDREX Rt, [Rn, #commencement] | Exclusive read word from retention location Rn + offset |
STREXB Rd, Rt, [Rn] | Sectional store byte in Rt to memory location Rn. Return status in Rd. |
STREXH Rd, Rt, [Rn] | Exclusive store half word in Rt to memory location Rn. Render condition in Rd. |
STREX Rd, Rt, [Rn, #offset] | Sectional store word in Rt from to location Rn + beginning. Return status in Rd. |
CLREX | Forcefulness the local sectional access monitor to clear so that next sectional store must fail. This is not a memory access instruction, but is listed here due to its usage. |
johnsonquichademad.blogspot.com
Source: https://www.sciencedirect.com/topics/engineering/pseudo-instruction
0 Response to "Using Labels as an Address to Read From in Thumb Assembly"
Postar um comentário