2

我在我的一个 ARM 目标 [x86] 中遇到了奇怪的崩溃。Windbg 崩溃点非法内存访问。

DRIVER_IRQL_NOT_LESS_OR_EQUAL (d1)

试图以过高的中断请求级别 (IRQL) 访问可分页(或完全无效)地址。这通常是由使用不正确地址的驱动程序引起的。

参数:Arg1:00000000,内存引用

Arg2:00000002,IRQL

Arg3:00000000,值 0 = 读操作,1 = 写操作

Arg4:8849fe99,引用内存的地址

这清楚地告诉我,我正在尝试在指令 0x8849fe99 处访问内存 0x00000000。0x8849fe99 代码的反汇编给出:

8849fe98 8818     ldrh        r0,[r3]

注册转储显示:

r0=00000000  r1=8458ac70  r2=00000000  r3=00000000  r4=00000000  r5=00000000  
r6=00000000  r7=00000000  r8=00000000  r9=00000000 r10=00000000 r11=8458ac20 
r12=b7edbed9  sp=8458ac18  lr=8849fe8b  pc=8849fe98 psr=400000b3 -Z--- Thumb

8849fe98 8818     ldrh        r0,[r3]                             00000000=????

所以,我试图访问 R3 的内存内容 - 但 R3 是 0x0000000 - 完全合乎逻辑。

但是有趣的部分来了。我尝试检查内存周围的代码并找到以下反汇编。

8849fe94 4620     mov         r0,r4

8849fe96 e8bd8818 pop         {r3,r4,r11,pc}

8849fe9a 0000     movs        r0,r0

8849fe9c 0000     movs        r0,r0

8849fe9e 0000     movs        r0,r0
  • 从上面的代码中,我注意到 0x8849FE96 处的代码是 32 位指令,应该一次性执行。

  • 但是调试器显示它尝试执行一条 16 位指令(位于 0x8849FE98)——这根本不是预期的!

  • 显然,我有一个执行有效操作的 32 位指令,但为什么我的 ARM 认为它是 16 位指令,并将我的完整指令 [e8bd8818] 分成两半并执行 16 位指令 [8818]?

  • 代码在 THUMB 模式下执行 - 这意味着处理器应该知道何时应该在 16 位模式下执行指令以及何时在 32 位模式下执行指令。

为什么处理器将指令视为 16 位?

4

0 回答 0