在主函数中,在
nexti
上的 bl
指令之后,gdb 调试器继续而不是停止。在 main 调用的函数中不会出现此问题(例如,我可以跳过 init_pin_output
中调用的函数)。我在设置中缺少什么?
开始.s:
@ ...
@ vector_table
@ ...
.thumb_func
.global reset
.align 4
reset:
ldr r2, PPB_BASE
ldr r1, VTOR_OFFSET
add r1, r1, r2
ldr r0, =vector_table
str r0, [r1]
ldr r1, SRAM_STRIPED_END
mov sp, r1
platform_entry:
ldr r1, =main
blx r1
mov r0, r0
bkpt #0 @ should not return
主要.s:
.thumb_func
.global main
.align 4
main:
push {lr}
@ ...
.init_led:
movs r0, #25
bl init_pin_output
mov r0, r0
@ ...
@ delay loop
@ ...
pop {pc}
.thumb_func
.global init_pin_output
.align 4
init_pin_output:
push {lr}
ldr r1, =out_pin
str r0, [r1]
ldr r0, out_pin
movs r1, #5 @ 5 - SIO
bl GPIO_function_select
ldr r0, out_pin
bl output_enable_pin
pop {pc}
.align 4
out_pin: .word 0
尝试从包装函数调用 main 并获得相同的结果。
On
backtrace
gdb 输出:“回溯已停止:前一帧与此帧相同(堆栈损坏?)”。
在检查了 sdk 生成的 .elf 文件的反汇编后,我没有遇到帧指针修改(因为它在拇指模式下无效)。
在我的代码中发现问题。事实证明,命名节(出于可读性原因)会破坏 GDB 的临时断点,因为它期望执行返回到“同一个”节(如“this”答案中所述)。我在 main.s 中的代码看起来更像是:
thumb_func
.global main
.align 4
main:
push {lr}
.clk:
bl setup_internal_clk
.init_gpio:
bl init_gpio
.init_ps2:
movs r0, #13
bl init_keyboard
@ ...
问题是,当从函数返回时,代码没有返回到
部分 - 它直接跳到下一个。解决方案是避免在节末尾进行函数调用,或者在函数调用后添加
nop
指令。