我有一个从C函数调用的ARM汇编函数。
在某些时候,我会这样做:
.syntax unified
.arm
.text
.globl myfunc
.extern printf
myfunc:
stmdb sp!, {r4-r11} // save stack from C call
......做点什么......
// (NOT SHOWN): Load values into r1 and r2 to be printed by format string above
ldr r0, =message // Load format string above
push {lr} // me attempting to preserve my stack
bl printf // actual call to printf
pop {lr} // me attempting to recover my stack
ldmia sp!, {r4-r11} // recover stack from C call
mov r0, r2 // Move return value into r0
mov pc, lr // Return to C
.section data
message:
.asciz "Output: %d, %d\n"
.end
有时运行,有时会崩溃,运行几次然后崩溃等等。它实际上是在准裸机上下文中运行的,因此我无法运行调试器。我99%肯定它是一个堆栈 - 或者对齐? - 根据此Printf Change values in registers, ARM Assembly和此Call C function from Assembly -- the application freezes at "call printf" and I have no idea why的内容。
任何人都可以提供一些关于如何运行上述代码的具体想法,也许这里有关于最佳实践的一般想法吗?理想情况下,我希望能够在我的汇编文件中多次调用相同的输出函数,以便随时调试。
提前致谢!
答案 0 :(得分:0)
我可以在该代码中看到以下问题:
.align 2
(可以是3或更高的值),位于函数入口点(myfunc:
)之前.align 2 // guarantee that instruction address is 4B aligned
myfunc:
预期堆栈将对齐8B。 push {lr}
打破了这一点。
message:
不必位于“数据”部分。它可能放在“ myfunc”后面的代码部分。检查链接器映射,确保实际存在数据并且地址已加载到r0
中。
既然是裸机,请检查堆栈是否设置正确,并为其保留足够的空间。