arm7tdmi汇编解释+崩溃调试
arm7tdmi assembly explanation + crash debugging
我目前正在调查在 arm7tdmi 架构上使用 gcc 4.2.1 编译时发生的崩溃(我可以按需使用 4.9.3)。我正在使用 LPC2387 并且正在重置 wdog。我使用 wdog 中断而不是 wdog 重置,所以当它以其他方式重置时,它进入我的处理程序,它保存状态并打印整个内存转储(仅限 64k)。所以基本上我知道 wdog 重置之前的寄存器,并且有一个堆栈显示所有调用历史记录。
在堆栈上,我可以看到大量对函数末尾的引用,并且我看到许多指令作为内存区域中的数据。我认为这将成为暂停的原因,然后是随后的 wdog 中断。知道会发生什么吗?
我想原因可能是取消引用函数指针时,但我的函数似乎很简单。它涉及许多硬件寄存器(中断、外设enable/disable)。
像这样:
2015/05/27 04:45:30: addr: 4000BF2C value:7FE00390 -->根据 gcc 4.2.1 和“.word 0x7fe00390”根据 4.9,这是 "svcvc 0x00e00390"。 3.
同样在函数的末尾,我在 gcc 4.9.3 中看到了这个
191d4: e89d6ff8 ldm sp, {r3, r4, r5, r6, r7, r8, r9, sl, fp, sp, lr}
191d8: e12fff1e bx lr
191dc: 7fe00390 .word 0x7fe00390
191e0: 40000044 .word 0x40000044
191e4: 00064de5 .word 0x00064de5
191e8: 00064dfb .word 0x00064dfb
191ec: 4000107c .word 0x4000107c
191f0: e0028000 .word 0xe0028000
191f4: e01fc000 .word 0xe01fc000
191f8: 40001084 .word 0x40001084
191fc: 4000113c .word 0x4000113c
19200: 3800b010 .word 0x3800b010
19204: 40002a78 .word 0x40002a78
19208: 40002ab4 .word 0x40002ab4
1920c: 40002aa0 .word 0x40002aa0
19210: 40001080 .word 0x40001080
19214: 400001a9 .word 0x400001a9
19218: e002c000 .word 0xe002c000
1921c: 40001134 .word 0x40001134
19220: 00064e0e .word 0x00064e0e
它在 gcc 4.2.1 上看起来像这样:
1953c: 7fe00390 svcvc 0x00e00390
19540: 40000044 andmi r0, r0, r4, asr #32
19544: 0006d74c andeq sp, r6, ip, asr #14
19548: 0006d764 andeq sp, r6, r4, ror #14
1954c: 400012d0 ldrmid r1, [r0], -r0
19550: e0028000 and r8, r2, r0
19554: e01fc000 ands ip, pc, r0
19558: 40001390 mulmi r0, r0, r3
1955c: 40001394 mulmi r0, r4, r3
19560: e002c040 and ip, r2, r0, asr #32
19564: 40002e54 andmi r2, r0, r4, asr lr
19568: e002c068 and ip, r2, r8, rrx
1956c: e002c000 and ip, r2, r0
19570: 40002e90 mulmi r0, r0, lr
19574: e002c02c and ip, r2, ip, lsr #32
19578: 3fffc000 svccc 0x00ffc000
1957c: 40002e7c andmi r2, r0, ip, ror lr
19580: 3fffc0a0 svccc 0x00ffc0a0
19584: 400012d4 ldrmid r1, [r0], -r4
19588: 400001a1 andmi r0, r0, r1, lsr #3
1958c: 400012d8 ldrmid r1, [r0], -r8
19590: 0006d778 andeq sp, r6, r8, ror r7
谁能解释一下这个函数的结尾是什么?什么是 .word 区域?为什么我会在堆栈上看到指向此区域的指针?
谢谢,
彼得
函数块结束后的字节是通常数据。
例如如果我有 void *somePtr = 0xABCDEF12;
那么您通常会得到一条 LDR 指令,该指令将值放入寄存器,假设是小端操作,您将看到十六进制的序列 12 EF CD AB
。
我目前正在调查在 arm7tdmi 架构上使用 gcc 4.2.1 编译时发生的崩溃(我可以按需使用 4.9.3)。我正在使用 LPC2387 并且正在重置 wdog。我使用 wdog 中断而不是 wdog 重置,所以当它以其他方式重置时,它进入我的处理程序,它保存状态并打印整个内存转储(仅限 64k)。所以基本上我知道 wdog 重置之前的寄存器,并且有一个堆栈显示所有调用历史记录。
在堆栈上,我可以看到大量对函数末尾的引用,并且我看到许多指令作为内存区域中的数据。我认为这将成为暂停的原因,然后是随后的 wdog 中断。知道会发生什么吗?
我想原因可能是取消引用函数指针时,但我的函数似乎很简单。它涉及许多硬件寄存器(中断、外设enable/disable)。
像这样:
2015/05/27 04:45:30: addr: 4000BF2C value:7FE00390 -->根据 gcc 4.2.1 和“.word 0x7fe00390”根据 4.9,这是 "svcvc 0x00e00390"。 3.
同样在函数的末尾,我在 gcc 4.9.3 中看到了这个
191d4: e89d6ff8 ldm sp, {r3, r4, r5, r6, r7, r8, r9, sl, fp, sp, lr}
191d8: e12fff1e bx lr
191dc: 7fe00390 .word 0x7fe00390
191e0: 40000044 .word 0x40000044
191e4: 00064de5 .word 0x00064de5
191e8: 00064dfb .word 0x00064dfb
191ec: 4000107c .word 0x4000107c
191f0: e0028000 .word 0xe0028000
191f4: e01fc000 .word 0xe01fc000
191f8: 40001084 .word 0x40001084
191fc: 4000113c .word 0x4000113c
19200: 3800b010 .word 0x3800b010
19204: 40002a78 .word 0x40002a78
19208: 40002ab4 .word 0x40002ab4
1920c: 40002aa0 .word 0x40002aa0
19210: 40001080 .word 0x40001080
19214: 400001a9 .word 0x400001a9
19218: e002c000 .word 0xe002c000
1921c: 40001134 .word 0x40001134
19220: 00064e0e .word 0x00064e0e
它在 gcc 4.2.1 上看起来像这样:
1953c: 7fe00390 svcvc 0x00e00390
19540: 40000044 andmi r0, r0, r4, asr #32
19544: 0006d74c andeq sp, r6, ip, asr #14
19548: 0006d764 andeq sp, r6, r4, ror #14
1954c: 400012d0 ldrmid r1, [r0], -r0
19550: e0028000 and r8, r2, r0
19554: e01fc000 ands ip, pc, r0
19558: 40001390 mulmi r0, r0, r3
1955c: 40001394 mulmi r0, r4, r3
19560: e002c040 and ip, r2, r0, asr #32
19564: 40002e54 andmi r2, r0, r4, asr lr
19568: e002c068 and ip, r2, r8, rrx
1956c: e002c000 and ip, r2, r0
19570: 40002e90 mulmi r0, r0, lr
19574: e002c02c and ip, r2, ip, lsr #32
19578: 3fffc000 svccc 0x00ffc000
1957c: 40002e7c andmi r2, r0, ip, ror lr
19580: 3fffc0a0 svccc 0x00ffc0a0
19584: 400012d4 ldrmid r1, [r0], -r4
19588: 400001a1 andmi r0, r0, r1, lsr #3
1958c: 400012d8 ldrmid r1, [r0], -r8
19590: 0006d778 andeq sp, r6, r8, ror r7
谁能解释一下这个函数的结尾是什么?什么是 .word 区域?为什么我会在堆栈上看到指向此区域的指针?
谢谢, 彼得
函数块结束后的字节是通常数据。
例如如果我有 void *somePtr = 0xABCDEF12;
那么您通常会得到一条 LDR 指令,该指令将值放入寄存器,假设是小端操作,您将看到十六进制的序列 12 EF CD AB
。