Reputation: 1
My ARM Envrionment is
root@linaro-developer:~# uname -a Linux linaro-developer 3.2.0 #7 SMP Thu Feb 28 16:20:18 PST 2013 armv7l armv7l armv7l GNU/Linux
And my assembly is
.section .text
.global _start
_start:
.code 32
#Thumb-Mode on
add r6, pc, #1
bx r6
.code 16
sub r4, r4, r4
mov r0, r4
ldr r2, =0x80047dbc
blx r2
ldr r2, =0x80047a0c
blx r2
However, When I'm trying to debug using gdb, pc is not going to sub r4, r4, r4 gdb state is
(gdb) x/3i $pc
=> 0x83c8: add r6, pc, #1
0x83cc: bx r6 ;r6 = 0x83d1
0x83d0: stcne 11, cr1, [r0], #-144 ; 0xffffff70
(gdb) x/3i 0x83d1
0x83d1: subs r4, r4, r4
0x83d3: adds r0, r4, #0
0x83d5: ldr r2, [pc, #4] ; (0x83dc)
subs r4, r4, r4 address is 0x83d1 0x83d1 is not aligned
Why my assembly code is located at unaligned address?
Upvotes: 0
Views: 2013
Reputation: 40357
A (full) ARM processor can execute instructions in either ARM or Thumb execution state - roughly speaking, the difference between the versatility of a full 32-bit instruction word, or the code-size efficiency of a more limited 16-bit one.
When branching to an address contained in a register, you have the ability to set the ARM or Thumb state with the LSB of the register contents, which appears to be what the code you are debugging is doing - branching to 0x83d1 will set Thumb state, but the actual address of the target instruction will be 0x83d0, which is 16-bit aligned.
In contrast, if branching to an immediate offset, you do not have the ability to set the mode with the LSB, but can instead choose between B/BL which retain state, or BX/BLX which toggle it.
Note that some smaller ARM cores intended for embedded usage only support Thumb mode, and cannot execute ARM instructions.
Upvotes: 3