我正在尝试调试用汇编程序编写的函数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.
答案 0 :(得分:4)
根据您发布的代码和反汇编,我猜测_sidata
中的地址无效。 _sidata
已加载到r3
,因此
ldr r3, [r3, r1]
执行,无效访问会导致另一个处理器复位,然后执行该处理器直到再次发出该指令。或类似的东西。
检查_sidata
中的内容。
一些补充说明:
我看到地址xxxx处的指令使用r0
,但我看不到r0
中reset_handler()
已初始化的位置。调用reset_handler()
的代码可能已经正确设置了r0
,但要确定我们必须看到异常向量表和重置向量实际指向的代码。 (我假设这是针对ARM7或类似的 - 让我知道我是否猜错了),其中异常向量表可能看起来像(从ethernut.de借来的),它会传递给名为{{1的标签重置:
_start
答案 1 :(得分:1)
嗯,这取决于: - )
on 取决于0x08005dc6
处的指示。很可能在重置处理程序中,您可能有一条指令,如:
0x08005dc6 jmp 0x08005dc6
会表现出这种行为。
你应该检查一下在那个地方的实际情况,例如:
disas 0x08005dc6 0x08005dcf