Using gnu assembler for arm.
MOV R1, #7
LDR R2, = ioadr
STR R1, [R2]
ioadr .word 0x20001000
This will fail because there is no colon after ioadr
so.s: Assembler messages:
so.s:5: Error: bad instruction `ioadr .word 0x20001000'
so
MOV R1, #7
LDR R2, = ioadr
STR R1, [R2]
ioadr: .word 0x20001000
this
LDR R2, = ioadr
is pseudo code that 1) is not supported by all tools for arm, 2) not supported in the same way. It says you want the address of ioadr loaded into r2. being pseudo code you should see what the tool does with it
unlinked:
Disassembly of section .text:
00000000 <ioadr-0xc>:
0: e3a01007 mov r1, #7
4: e59f2004 ldr r2, [pc, #4] ; 10 <ioadr+0x4>
8: e5821000 str r1, [r2]
0000000c <ioadr>:
c: 20001000 .word 0x20001000
10: 0000000c .word 0x0000000c
linked
Disassembly of section .text:
00008000 <ioadr-0xc>:
8000: e3a01007 mov r1, #7
8004: e59f2004 ldr r2, [pc, #4] ; 8010 <ioadr+0x4>
8008: e5821000 str r1, [r2]
0000800c <ioadr>:
800c: 20001000 andcs r1, r0, r0
8010: 0000800c andeq r8, r0, ip
So you can now use this against the architectural reference manual and trivially see that it is loading the ADDRESS of ioadr into r2 not 0x20001000
So when the store happens it stores it writes over the 0x20001000 not a write to 0x20001000
Change it to different pseudo code, remove the equals
MOV R1, #7
LDR R2, ioadr
STR R1, [R2]
ioadr: .word 0x20001000
Now it does what the book seems to be describing.
Disassembly of section .text:
00008000 <ioadr-0xc>:
8000: e3a01007 mov r1, #7
8004: e59f2000 ldr r2, [pc] ; 800c <ioadr>
8008: e5821000 str r1, [r2]
0000800c <ioadr>:
800c: 20001000 andcs r1, r0, r0
The load loads the value 0x20001000 into r2 so that the store then is actually written to 0x20001000.
DCD and .word are not the only assembly language issues that you needed to look at. As you can see now above. If you have any questions then assemble and disassemble and look up the instructions yourself first then if still confused post it along with the source.
I suspect the book is wrong, and that is another life lesson. Documentation is buggy, assume that it is, including the arm docs. If you have access to arms tools that match the assembly language in the book (if the book is halfway decent it will specify the exact tool and version, I did not look) then assemble and disassemble.
As you can see in the many answers on this site related to the equal sign pseudo code for ARM, for example
ldr r0,=0x12345678
ldr r1,=0x00000007
You will find that gnu will choose the optimal instruction(s). But other tools, if they support it at all, might take it literally and generate a ldr using a literal pool. The first one above will probably be a pc relative load from a literal pool as shown in the examples above based on your code. the latter, with gnu, will generate a mov r1,#7 instead of a pc relative load. So when using these kinds of things, use with care. Most important understand that assembly language is specific to the tool, not the target. And sometimes the version of the tool. In the same way it takes work to convert a c program to java or python it takes work to convert assembly language to one of arms tools (note that arm has had a series of tools over time, re-writes or purchases of smaller companies) to gnu binutils and back. It is literally a conversion from one programming language to another, just not as harsh as C to python.