【问题标题】:printing new lines with printf assembly使用 printf 程序集打印新行
【发布时间】:2012-01-21 22:26:29
【问题描述】:

您好,我正在尝试编写一些使用 printf 打印给定字符串的汇编代码。我在 .data 部分中使用之前声明了我的字符串,测试示例如下所示:

extern printf
extern fflush

LINUX        equ     80H      ; interupt number for entering Linux kernel
EXIT         equ     60       ; Linux system call 1 i.e. exit ()

section .data
    outputstringfmt: db "%s", 0
    sentence0: db "Hello\nWorld\n", 0


segment .text
    global  main


main:
    mov r8, sentence0
    push r8
    call print_sentence
    add rsp, 8
    call os_return

print_sentence:
    push rbp
    mov rbp, rsp
    push r12
    mov r12, [rbp + 16]
    push rsi
    push rdi
    push r8
    push r9
    push r10
    mov rsi, r12
    mov rdi, outputstringfmt
    xor rax, rax
    call printf
    xor rax, rax
    call fflush
    pop r10
    pop r9
    pop r8
    pop rdi
    pop rsi
    pop r12
    pop rbp
    ret

os_return:
    mov  rax, EXIT      ; Linux system call 1 i.e. exit ()
    mov  rdi, 0     ; Error code 0 i.e. no errors
    syscall     ; Interrupt Linux kernel 64-bit

然后我编译如下:

nasm -f elf64 test.asm; gcc -m64 -o test test.o

最后运行:

./test

我的输出如下:

Hello\nWorld\n

我真的不想将句子0分成以下内容:

sentence0: db "Hello", 10, 0
sentence1: db "World", 10, 0

然后调用 print 两次。有没有更好的方法?

提前致谢!

【问题讨论】:

  • 更好的方法到底是什么?
  • 我不想将字符串拆分为多个字符串声明。我只想能够将换行符打印为字符串的一部分,并且只需要在 sentence0 中声明它。
  • 你是说 \n:s 是逐字打印的吗?
  • 目前他们是,但我不希望他们成为。我希望它们打印为换行符。

标签: gcc assembly newline printf nasm


【解决方案1】:

NASM 接受单引号 ('...') 或双引号 ("...") 中的字符串,它们是等效的,不提供任何转义;或在反引号 (`...`) 中提供对 C 样式转义的支持,这正是您想要的。

(见section 3.4.2, "Character Strings", in the documentation。)

要在内存中的数据中获取实际的 ASCII 换行符,而不是文字反斜杠 n:

sentence0: db `Hello\nWorld\n`, 0

或者手动操作:

sentence0: db 'Hello', 10, 'World`, 10, 0

YASM(另一个 NASM 语法汇编器)不接受反引号,因此手动选项是您唯一的选择。

顺便说一句,如果您的格式字符串中没有任何实际格式(省略尾随换行符),您可以调用 puts 而不是 printf

【讨论】:

    【解决方案2】:

    您在要输出的字符串中有换行符 (\n)。它们应该是格式字符串,被视为换行符。这解决了你一半的问题:

    outputstringfmt: db "%s\n%s\n", 0
    sentence0: db "Hello", 0
    sentence1: db "World", 0
    

    像这样应该在每个单词后打印换行符:

    outputstringfmt: db "%s", 0
    sentence0: db "Hello", 10 , "World", 10 , 0
    

    【讨论】:

    • 我无法控制字符串中新行的位置,这只是一个测试示例。我已经尝试在 C 中使用 printf 并且您不需要在格式中指定换行符,它似乎仍然可以很好地处理它们。我想知道为什么我的程序集也不处理它​​们?
    • 可能对实现敏感。我不太熟悉它“应该”如何表现。
    • C 编译器将 \n 转换为单个 0xA 字符。它是编译器中的字符串解析器,而不是 printf。反汇编 nasm 正在生成的内容,也许 nasm 可以选择像 C 编译器而不是像汇编器一样解析。
    猜你喜欢
    • 2020-09-29
    • 1970-01-01
    • 2014-07-28
    • 2016-08-11
    • 2011-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多