assembly - 程序计数器发生奇怪的变化,没有任何指令修改它(qemu-arm,裸机)

标签 assembly segmentation-fault gdb arm qemu

我目前正在尝试使我编写的程序在裸机臂设备上运行。由于我还没有该设备,因此我尝试使用 qemu 在 Arm 仿真上运行代码。

我使用以下命令运行我的代码:qemu-system-arm -M realview-pb-a8 -m 128M -ngraphic -s -S -kernel myprog

即使我使用其他板设置,执行也会始终卡在同一点。这是它被卡住的地方(一些 openSSL 代码):

   0x398b4 <EVP_CipherInit_ex+884>         ldr    r3, [r11, #-24]
   0x398b8 <EVP_CipherInit_ex+888>         ldr    r3, [r3]
   0x398bc <EVP_CipherInit_ex+892>         ldr    r12, [r3, #20]
   0x398c0 <EVP_CipherInit_ex+896>         ldr    r0, [r11, #-24]
   0x398c4 <EVP_CipherInit_ex+900>         ldr    r1, [r11, #-36] ; 0x24  
   0x398c8 <EVP_CipherInit_ex+904>         ldr    r2, [r11, #4] 
   0x398cc <EVP_CipherInit_ex+908>         ldr    r3, [r11, #8]
   0x398d0 <EVP_CipherInit_ex+912>         mov    lr, pc
   0x398d4 <EVP_CipherInit_ex+916>         bx     r12
[..]
-> 0x391e4 <aes_init_key>          push   {r11, lr}  <- Strange thing happens at this instruction.
   0x391e8 <aes_init_key+4>        add    r11, sp, #4
   0x391ec <aes_init_key+8>        sub    sp, sp, #40     ; 0x28
   0x391f0 <aes_init_key+12>       str    r0, [r11, #-24]
   0x391f4 <aes_init_key+16>       str    r1, [r11, #-28]

紧接着 0x391e4 处的指令,$pc 更改为 0x391e6 而不是 0x391e8。这不是一个有效的地址,因此它在执行时直接跳转到文件的开头。如果我在调试器中将 $pc 更改为正确的值,我会到达 0x391e8,但 $pc 再次设置为错误的值(0x391ea)。我无法用我的代码以外的其他代码重现此行为。

这是在发生糟糕的事情之前主寄存器的转储。

r0   0xe28db004 -494030844    r1   0x7aeb8  503480
r2      0x7aea8     503464    r3       0x1       1
r4      0x7df98     515992    r5   0x7dfa8  516008
r6          0x0          0    r7       0x0       0
r8          0x0          0    r9       0x0      0
r10     0x60000     393216    r11  0x7ae34  503348
r12     0x391e5     233957    sp   0x7ae08  0x7ae08 <__malloc_av_+252>
lr      0x398d8     235736    pc   0x391e6  0x391e6 <aes_init_key+2>
cpsr 0x200001f3  536871411

紧随其后的是:

r0   0xe28db004  -494030844   r1     0x7aeb8    503480
r2      0x7aea8      503464   r3         0x1         1
r4      0x7df98      515992   r5     0x7dfa8    516008
r6          0x0           0   r7         0x0         0
r8          0x0           0   r9         0x0         0 
r10     0x60000      393216   r11    0x7ae34    503348
r12     0x391e5      233957   sp     0x7e000   0x7e000
lr      0x391e8      233960   pc         0x8       0x8
cpsr 0x200001db   536871387

我该如何解决这个问题?这可能是编译器错误吗?

我尝试了这些编译器标志:-marm -mthumb-interwork

最佳答案

2 个字节的变化听起来很像拇指模式,而且实际上您的 cpsr 位 #5 已设置。要么这确实是拇指代码,在这种情况下您将其反汇编错误,要么它是arm代码,在这种情况下它在拇指模式下被错误地调用。

关于assembly - 程序计数器发生奇怪的变化,没有任何指令修改它(qemu-arm,裸机),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28632109/

相关文章:

assembly - ARM 汇编中 32 位字内的高效按字节循环

c++ - 有没有更好的方法来实现这种内存管理?

c++ - 自己调用拷贝构造函数

组装 ADC(带进位的加法)

c - 快速舍入数字 >= 0 到 2 的特定幂的倍数

linux - 更改内核页面权限以允许用户访问

python-3.x - 训练多个 Keras NN 模型时出现段错误(核心转储)

c - 运行时段错误,但调试时成功

c++ - Netbeans-7.4 中的 gdb 用于 C++ 调试

gcc - gdb - 如何进入多行宏