用printf组件打印新行

时间:2011-12-16 11:16:20

标签: gcc assembly newline printf nasm

您好我正在尝试编写一些使用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

然后调用打印两次。有没有更好的方法呢?

提前致谢!

2 个答案:

答案 0 :(得分:10)

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

答案 1 :(得分:3)

您要输出的字符串中有换行符(\ 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