ARM:2个printf导致分段错误

3

我为ARM编写了一个“Hello World”程序,它运行得很好。但是,当我重复printf调用(以打印两次“Hello World”)时,程序开始出现“分段错误”。

这是带有双重printf调用的代码:

.extern printf
.global main

main:
        push {ip,lr}
        ldr r0, =test
        bl printf
        bl printf

        mov r0, #0
        pop {ip,pc}

        test: .asciz "hello world\n"

有什么线索可以找出问题的原因并解决它吗?

3
重新加载 R0printf 可以改变它,就像打印的字符一样。 - artless noise
就这样了,谢谢。你不想把它发布为答案,这样我就可以选择它作为正确的答案吗? - Daniel Scocco
我从来不明白为什么人们不给评论点赞。有些东西太琐碎了,不值得回答;-) - FrankH.
2个回答

6
ARM EABI规定被调用方可以更改 r0-r3 和 r12 寄存器的值,因此你的 r0 不再保存字符串的地址,实际上它保存的是 printf 调用的返回值(在这个例子中是 12)。接下来的 printf 调用会尝试访问内存地址 0xC 上的字符串,从而导致进程崩溃。
要使双重 printf 正常工作,您需要像这样操作:
ldr r0, =test
bl printf
ldr r0, =test
bl printf

3

r0 不仅是第一个参数,还将返回值存储在其中。在第一次调用 printf() 后,它将不再包含指向字符串的有效指针,而是会包含打印的字符数。您应该使用以下代码:

    ldr r0, =test
    bl printf
    ldr r0, =test
    bl printf

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接