【问题标题】:why ARM instruction address is not align on my ARM Environment?为什么 ARM 指令地址在我的 ARM 环境中不对齐?
【发布时间】:2015-02-22 17:19:32
【问题描述】:

我的 ARM 环境是

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

我的程序集是

.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

但是,当我尝试使用 gdb 进行调试时,pc 不会 sub r4, r4, r4 gdb 状态是

(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 地址为 0x83d1 0x83d1 未对齐

为什么我的汇编代码位于未对齐的地址?

【问题讨论】:

  • pc 会先到 0x83d0,然后再到 0x83d2 (Thumb) 但是,我想执行 'subs r4, r4, r4'。我该怎么办?当我执行我的汇编代码时,它会发生“段错误”
  • 触发故障的访问地址是什么?
  • (gdb) x/3i $pc => 0x83c8: 添加 r6, pc, #1 0x83cc: bx r6 0x83d0: stcne 11, cr1, [r0], #-144 ; 0xffffff70 (gdb) ni 无法访问地址 0x0 0x000083cc 的内存?? () (gdb) si 0x000083d0 在?? () (gdb) x/3i $pc => 0x83d0: stcne 11, cr1, [r0], #-144 ; 0xffffff70 0x83d4: ldrmi r4, [r0, r1, lsl #20] 0x83d8: ldrmi r4, [r0, r1, lsl #20] (gdb) ni 0x000083d2 在?? () (gdb) x/3i $pc => 0x83d2: bmi 0x4f45a 0x83d6: bmi 0x5a21e 0x83da: ldcvc 7, cr4, [r12, #576]! ; 0x240 (gdb) c 继续。程序收到信号 SIGSEGV,分段错误。 0x80047dbc 在?? ()
  • Sorry Look this trace is so hard :(
  • 哦,0x80047dbc是prepare_kernel_cred地址。为什么这个地址没有映射?我使用grep _cred /proc/kallsyms 命令检查此地址

标签: debugging assembly gdb arm thumb


【解决方案1】:

一个(完整的)ARM 处理器可以在 ARM 或 Thumb 执行状态下执行指令 - 粗略地说,是完整 32 位指令字的多功能性或更有限的 16 位代码大小效率之间的区别一个。

当跳转到寄存器中包含的地址时,您可以使用寄存器内容的 LSB 设置 ARM 或 Thumb 状态,这似乎是您正在调试的代码正在执行的操作 - 跳转到 0x83d1 将设置Thumb 状态,但目标指令的实际地址是 0x83d0,是 16 位对齐的。

相比之下,如果分支到立即偏移,则无法使用 LSB 设置模式,但可以在保留状态的 B/BL 或切换状态的 BX/BLX 之间进行选择。

请注意,一些用于嵌入式使用的较小 ARM 内核支持 Thumb 模式,不能执行 ARM 指令。

【讨论】:

  • 请注意,PC 寄存器本身总是包含正确对齐的地址(如果没有,您会遇到错误) - 写入的值 的 lsb交互操作指令中的 PC 很重要。实际状态在 CPSR 的 T 位结束。当然,gdb 选择如何表示事物可能是另一回事。
  • 代码位于 0x83d0,而不是 0x83d1(尽管您的调试器有助于将其显示在从您的条目派生的对齐屏蔽地址处)。它不工作吗?如果追踪它会发生什么?
猜你喜欢
  • 2014-06-12
  • 2019-05-17
  • 2012-05-25
  • 2019-05-25
  • 1970-01-01
  • 2012-08-19
  • 1970-01-01
  • 2020-02-13
  • 2023-03-12
相关资源
最近更新 更多