1

我有一个用 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

4

2 回答 2

4

问题是你没有保存lr

     bl _write
     add sp, #64
     bx lr

bl _write将覆盖lrwhich 然后指向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 进行字节存储。

于 2012-04-18T18:26:49.227 回答
3

该函数将 32 位值压入未对齐的堆栈指针地址。它应该strb用于写入单个字节。对于 unaligned str,ARM Architecture Reference Manual 说:

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 情况,您的堆栈中可能会出现垃圾。

于 2012-04-18T18:21:21.113 回答