【问题标题】:Can't get newline to print with ARM Linux assembly无法使用 ARM Linux 程序集打印换行符
【发布时间】:2016-08-17 23:19:08
【问题描述】:

我从一本 Raspberry Pi 汇编语言书中的代码开始。它以二进制形式打印出 15:

00000000000000000000000000001111pi@raspberrypi:$

我想在最后添加一个换行符,所以我实现了代码的_newline:new: .ascii "\n" 部分。

我重新组装了它,但输出保持不变。我在输出换行符时错过了什么吗?

        .global _start
_start:
        mov r6, #15  
        mov r10, #1
        mov r9, r10, lsl #31
        ldr r1, =string
_bits:
        tst r6, r9
        moveq r0, #48
        movne r0, #49
        str r0, [r1]
        mov r8, r6
        bl _write
        mov r6, r8

        movs r9, r9, lsr #1
        bne _bits

_newline:
        mov r0, #1
        mov r2, #1
        mov r7, #4
        ldr r1, =new
        swi 0

_exit:
        mov r7, #1
        swi 0  
_write:
        mov r0, #1
        mov r2, #1
        mov r7, #4
        swi 0
        bx lr

.data
string: .ascii " "
new:    .ascii "\n"

strace输出的最后几行是:

write(1, "1", 11) = 1
write(1, "1", 11) = 1
write(1, "1", 11) = 1
write(1, "1", 11) = 1
write(1, "\0", 11) = 1
exit(1) =?
+++ exited with 1 +++

【问题讨论】:

  • 尝试使用strace ./a.out 看看你的进程做了什么系统调用。
  • 另外,我会通过将字符写入一个 17 字节的缓冲区来实现这一点,并在末尾添加一个换行符。将 ASCII 0 或 1 存储到缓冲区中,然后使用单个系统调用将其写入,而不是为每个字节单独调用 write()。不过,你的方法行得通,只是效率较低。
  • strace 的最后几行给了我这个:write(1, "1", 11) = 1 write(1, "1", 11) = 1 write(1, "1", 11) = 1 写入(1, "1", 11) = 1 写入(1, "\0", 11) = 1 退出(1) =? +++ 以 1 +++ 退出
  • 我几乎没有学习手臂组装,所以我只是按照书中的例子,但我也会研究你的方式。
  • 我将您的 strace 输出添加到您的问题中,就像您应该拥有的那样,而不是将其作为评论发布。至少您选择了要包含的 strace 输出的正确部分。 :) 它让我在大约 10 秒内找到了解决方案:我只需要问:什么可以用 \0 覆盖 \n?然后回头看看另一家商店,因为我知道它正在存储相邻的数据。

标签: linux assembly raspberry-pi arm system-calls


【解决方案1】:

你的 strace 输出就是线索:write(1, "\0", 11) = 1 告诉我们你写了一个 0 字节而不是\n 的 ASCII 编码。


当您str r0, [r1] 时,您存储了 4 个字节。

那家商店的目的地是

.data
string: .ascii " "
new:    .ascii "\n"

这是真的:

.data
string: .byte   ' '
new:    .byte   '\n'

因此,每次您将 '0''1' 存储到 string 时,您还会多写 3 个零字节,破坏您的 '\n' 和超出数据部分末尾的 2 个字节。 (它不会出现段错误,因为您不在页面末尾。)


最简单的解决方法是使用单字节存储:strb r0, [r1],而不是字大小的str

【讨论】:

  • 谢谢它的工作。你的解释很有意义。
  • @MarcoLugo:我很高兴它有帮助。 :) 正确的解释是 SO 的全部内容,IMO,而不仅仅是代码转储。这就是为什么我们喜欢只有一个问题的好问题,这样可以得到好的答案,将来可能对其他人有用。
猜你喜欢
  • 1970-01-01
  • 2020-09-29
  • 1970-01-01
  • 2018-04-17
  • 2012-01-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-10
相关资源
最近更新 更多