ARM汇编函数的问题?

时间:2012-04-18 18:07:34

标签: linux assembly arm

我有一个用ARM汇编程序编写的简单函数。它第一次运行时,一切都按预期工作(它打印BOOT\n)。但是,第二次执行该功能时,不会打印任何内容。

.globl __printTest
.text
.align 2

__printTest:
 sub sp, #64 /* yes, I know this is too much */

 mov r0, #66
 str r0, [sp]
 mov r0, #79
 str r0, [sp, #1]
 mov r0, #79
 str r0, [sp, #2]
 mov r0, #84
 str r0, [sp, #3]
 mov r0, #10
 str r0, [sp, #4]

 mov r0, #0
 mov r1, sp
 mov r2, #5

 bl _write
 add sp, #64

 bx lr

可能是什么问题?我怀疑这会以某种方式搞砸缓冲区,使其不再有效。 Write是一个使用write指令在Linux上调用svc系统调用的函数。

2 个答案:

答案 0 :(得分:4)

问题是您没有保存lr

     bl _write
     add sp, #64
     bx lr

bl _write将覆盖lr,然后指向add sp, #64,因此您的bx lr只会导致最后两条指令无限循环。

如果您修改代码,它应该可以工作:

__printTest:
 push {lr}
 sub sp, #64 /* yes, I know this is too much */
 ....
 bl _write
 add sp, #64
 pop {pc}

正如另一个答案中所说,你也应该使用strb而不是str来进行字节存储。

答案 1 :(得分:3)

此函数将32位值推入未对齐的堆栈指针地址。它应该使用strb来写单个字节。对于未对齐的str,ARM体系结构参考手册说:

if UnalignedSupport() || address<1:0> == ‘00’ then
    MemU[address,4] = R[t];
else // Can only occur before ARMv7
    MemU[address,4] = bits(32) UNKNOWN;

因此,根据您的配置,如果您遇到UNKNOWN案例,您可能会在堆栈中收到垃圾邮件。