I'm currently playing around a bit with assembler on a Cortex-M3 microcontroller. I'm not sure if this is important, but here you go.
I need to write a value into to a certain address in memory. Here is what I tried:
LDR R4, =__cs3_interrupt_vector_cortex_m
STR R4, [=VTOR]
But it seems like I need to reference the VTOR address relative to the PC register. The question is if there is a way to not reference the address relativ and let this do automatically (so that it would basically look like my approach).
I'm using GNU Assembler.
You need to load the destination address to a register. I assume that VTOR
is a memory address or 'C' pointer and __cs3_interrupt_vector_cortex_m
is a constant. Ie, you wish to write a 32bit constant to an address. If this is the case then,
; Get value __cs3_interrupt_vector_cortex_m to r4
ldr r4, =__cs3_interrupt_vector_cortex_m
ldr r5, =VTOR ; address 'VTOR' to r5.
str r4, [r5] ; write the constant to 'VTOR' address.
The ARM/Thumb/Thumb2 is a load-store architecture. You can not use memory operands in the load and store instructions. This simplifies the CPU design, but is different from M68K and x86 assembler.
The syntax ldr rX, =val
is explained in the Gnu assembler info pages. Generally it will convert to the following,
ldr rX, [pc, #offset]
...
offset: .word val ; your constant is stored here.
The pseudo-op .ltorg
tells the assembler to dump the literal table; the offset portion of code above. You can add an .ltorg
anywhere between sub-routines, etc.
You can not use the syntax str r4,[=VTOR]
as the equals syntax is only a short-cut for use with ldr
. For example,
ldr rX,=7 ; is really 'mov rx,#7' in all modes.
ldr rX,=0xff ; is 'mov rx,#0xff' for ARM and '[pc,#offset]' for thumb.
ldr rx,=0x12345678 ; will use the [pc, #offset] for all modes.
You can use the ldr rX,=VTOR
syntax to get the address to a register. It then takes another instruction like str rY, [rX]
to actually write to that address.
Constants are encoded inside an instruction so the constant range is very limited especially in thumb mode. I guess you are using thumb2 which may have more range.