程序计数器没有推进

时间:2012-03-22 14:21:42

标签: assembly embedded arm

我正在尝试调试用汇编程序编写的函数Reset_Handler()(我不明白,但它是作为标准库的一部分提供的)。使用GDB,我使用ni完成每条指令。这是我得到的:

(gdb) ni
0x08005dc4 in Reset_Handler ()
(gdb) ni
0x08005dc6 in Reset_Handler ()
(gdb) ni
0x08005dc6 in Reset_Handler ()
(gdb) ni
0x08005dc6 in Reset_Handler ()
(gdb) ni
0x08005dc6 in Reset_Handler ()

实际上,程序指针在0x08005dc6上“卡住”。这是正常行为,还是每次ni时程序指针都应该前进?以下是Reset_Handler()的开头:

    .section  .text.Reset_Handler
  .weak  Reset_Handler
  .type  Reset_Handler, %function
Reset_Handler:  

/* Copy the data segment initializers from flash to SRAM */  
  movs  r1, #0
  b  LoopCopyDataInit

CopyDataInit:
  ldr  r3, =_sidata
  ldr  r3, [r3, r1]
  str  r3, [r0, r1]
  adds  r1, r1, #4

LoopCopyDataInit:
  ldr  r0, =_sdata
  ldr  r3, =_edata
  adds  r2, r0, r1
  cmp  r2, r3
  bcc  CopyDataInit
  ldr  r2, =_sbss
  b  LoopFillZerobss
/* Zero fill the bss segment. */  
FillZerobss:
  movs  r3, #0
  str  r3, [r2], #4

编辑:以下是反汇编的说明:

disas
Dump of assembler code for function Reset_Handler:
   0x08005dc0 <+0>:     movs    r1, #0
   0x08005dc2 <+2>:     b.n     0x8005dcc <LoopCopyDataInit>
   0x08005dc4 <+4>:     ldr     r3, [pc, #40]   ; (0x8005df0 <LoopFillZerobss+16>)
=> 0x08005dc6 <+6>:     ldr     r3, [r3, r1]
   0x08005dc8 <+8>:     str     r3, [r0, r1]
   0x08005dca <+10>:    adds    r1, #4
   0x08005dcc <+0>:     ldr     r0, [pc, #36]   ; (0x8005df4 <LoopFillZerobss+20>)
   0x08005dce <+2>:     ldr     r3, [pc, #40]   ; (0x8005df8 <LoopFillZerobss+24>)
   0x08005dd0 <+4>:     adds    r2, r0, r1
   0x08005dd2 <+6>:     cmp     r2, r3
   0x08005dd4 <+8>:     bcc.n   0x8005dc4 <Reset_Handler+4>
   0x08005dd6 <+10>:    ldr     r2, [pc, #36]   ; (0x8005dfc <LoopFillZerobss+28>)
   0x08005dd8 <+12>:    b.n     0x8005de0 <LoopFillZerobss>
   0x08005dda <+0>:     movs    r3, #0
   0x08005ddc <+2>:     str.w   r3, [r2], #4
   0x08005de0 <+0>:     ldr     r3, [pc, #28]   ; (0x8005e00 <LoopFillZerobss+32>)
   0x08005de2 <+2>:     cmp     r2, r3
   0x08005de4 <+4>:     bcc.n   0x8005dda <FillZerobss>
   0x08005de6 <+6>:     bl      0x8005c64 <SystemInit>
   0x08005dea <+10>:    bl      0x8000184 <main>
   0x08005dee <+14>:    bx      lr
End of assembler dump.

2 个答案:

答案 0 :(得分:4)

根据您发布的代码和反汇编,我猜测_sidata中的地址无效。 _sidata已加载到r3,因此

 ldr     r3, [r3, r1]
执行

,无效访问会导致另一个处理器复位,然后执行该处理器直到再次发出该指令。或类似的东西。

检查_sidata中的内容。


一些补充说明:

我看到地址xxxx处的指令使用r0,但我看不到r0reset_handler()已初始化的位置。调用reset_handler()的代码可能已经正确设置了r0,但要确定我们必须看到异常向量表和重置向量实际指向的代码。 (我假设这是针对ARM7或类似的 - 让我知道我是否猜错了),其中异常向量表可能看起来像(从ethernut.de借来的),它会传递给名为{{1的标签重置:

_start

答案 1 :(得分:1)

嗯,这取决于: - )

on 取决于0x08005dc6处的指示。很可能在重置处理程序中,您可能有一条指令,如:

0x08005dc6 jmp 0x08005dc6

会表现出这种行为。

你应该检查一下在那个地方的实际情况,例如:

disas 0x08005dc6 0x08005dcf