Thumb instructions are in fact only 16 bits long! But as you say, even on full-fat ARM there's not room for a 32-bit immediate.I think the problem is I am using ARM thumb instructions (which are 32 bits) and I'm trying to put a 32 bit address / operand into an instruction which can at maximum be 32 bits long (opcode + operand needs to be 32 bits max).
Many of the ARM CPUs now have pairs of instructions that can load a 32-bit value in two halves (so two 32-bit instructions each with a 16-bit immediate field in them), but not on a lowly CortexM0+ that only supports the 16-bit instructions.
There's various ways around this, but the original way right back to ARM1 and still appropriate on CortexM0 is 'constant pools' - constants placed alongside the instructions being executed but won't actually themselves get executed (so after an unconditional branch is a handy place), and they can then be loaded into a register with a PC-relative load instruction.
The assembler makes this easy for you by automatically creating the constant pools with an '=' in the syntax.
I've fixed up your hello.s so that it compiles:
Code:
.syntax unified .cpu cortex-m0plus .thumb .alignhello: ldr r0, =0x4000f000 movs r1, #32 str r1, [r0] b hello
Code:
Disassembly of section .text:00000000 <hello>: 0: 4801 ldr r0, [pc, #4] ; (8 <hello+0x8>) 2: 2120 movs r1, #32 4: 6001 str r1, [r0, #0] 6: e7fb b.n 0 <hello> 8: 4000f000 .word 0x4000f000
Note that I don't think this was your original problem - you hadn't got that far due to syntax errors, notably use of round brackets rather than square.
The .cpu directive isn't necessary if you specify the CPU type on the command line with -mcpu= and maybe you can specify the .thumb that way too.
Statistics: Posted by arg001 — Tue Jul 02, 2024 12:03 pm