In Wiley's Practical Reverse Engineering book, page 59, the following example is used to explain the LDM/STM instructions.
Shouldn't line 30 show R6 with the values of r3, r4, r5? Doesn't line 10 store the values in R6 at the memory locations of the destination?
02: Breakpoint 1 at 0x8344
03: (gdb) disas main
04: Dump of assembler code for function main:
05: 0x00008344 <+0>: ldr r6, =mem ; edited a bit
06: 0x00008348 <+4>: mov r0, #10
07: 0x0000834c <+8>: mov r1, #11
08: 0x00008350 <+12>: mov r2, #12
09: 0x00008354 <+16>: ldm r6, {r3, r4, r5} ; IA mode
10: 0x00008358 <+20>: stm r6, {r0, r1, r2} ; IA mode
11: …
12: (gdb) r
13: Breakpoint 1, 0x00008344 in main ()
14: (gdb) si
15: 0x00008348 in main ()
16: (gdb) x/3x $r6
17: 0x1050c <mem>: 0x00000001 0x00000002 0x00000003
18: (gdb) si
19: 0x0000834c in main ()
20: …
21: (gdb)
22: 0x00008358 in main ()
23: (gdb) info reg r3 r4 r5
24: r3 0x1 1
25: r4 0x2 2
26: r5 0x3 3
27: (gdb) si
28: 0x0000835c in main ()
29: (gdb) x/3x $r6
30: 0x1050c <mem>: 0x0000000a 0x0000000b 0x0000000c
The fact that your ldm
instruction took what was at the memory location pointed to by r6
and loaded that into r3/4/5
(a memory to register operation), should be a dead giveaway that stm
will do the opposite (a register to memory operation).
In other words, it will store r0/1/2
(which you'e set to 10/11/12
decimal or a/b/c
hexadecimal) into the memory pointed to by r6
, exactly what you're seeing:
30: 0x1050c <mem>: 0x0000000a 0x0000000b 0x0000000c
This matches the other load/store instructions on ARM and, indeed, quite a lot of other CPUs, you:
User contributions licensed under CC BY-SA 3.0