从ARM组装函数调用printf时出现堆栈问题

时间:2014-05-23 03:32:00

标签: debugging assembly stack arm printf

我有一个从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的内容。

任何人都可以提供一些关于如何运行上述代码的具体想法,也许这里有关于最佳实践的一般想法吗?理想情况下,我希望能够在我的汇编文件中多次调用相同的输出函数,以便随时调试。

提前致谢!

1 个答案:

答案 0 :(得分:0)

我可以在该代码中看到以下问题:

  1. .align 2(可以是3或更高的值),位于函数入口点(myfunc:)之前
.align 2 // guarantee that instruction address is 4B aligned
myfunc:
    如注释中所述,
  1. 预期堆栈将对齐8B。 push {lr}打破了这一点。

  2. message:不必位于“数据”部分。它可能放在“ myfunc”后面的代码部分。检查链接器映射,确保实际存在数据并且地址已加载到r0中。

既然是裸机,请检查堆栈是否设置正确,并为其保留足够的空间。