Gcc 使用printf assembly打印新行

Gcc 使用printf assembly打印新行,gcc,assembly,newline,printf,nasm,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

嗨,我正在尝试编写一些汇编代码,使用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
Hello\nWorld\n
然后我将编译如下:

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
Hello\nWorld\n
最后运行:

./test
我的输出如下:

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
Hello\nWorld\n
我真的不想把句子0分成以下几部分:

sentence0: db "Hello", 10, 0
sentence1: db "World", 10, 0
然后调用打印两次。有更好的方法吗

提前谢谢

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

NASM接受单引号(
“…”
)或双引号(
“…”
)中的字符串,它们是等效的,并且不提供任何转义;或者使用反引号(
`…
),它提供了对C风格转义的支持,这正是您所需要的

(见附件。)

要在内存中的数据中获取实际的ASCII换行符,而不是反斜杠n,请执行以下操作:

sentence0: db `Hello\nWorld\n`, 0
或者手动操作:

sentence0: db 'Hello', 10, 'World`, 10, 0
YASM(另一个NASM语法汇编程序)不接受反勾号,因此手动选项是您唯一的选择


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

更好的方法是做什么?我不想将字符串拆分为多个字符串声明。我只希望能够将换行符作为字符串的一部分打印出来,并且只需要在第0句中声明它。您是说\n:s是逐字打印的吗?目前是,但我不希望这样。我希望它们以换行符的形式打印。我无法控制字符串中的新行的位置。这只是一个测试示例。我已经尝试在C中使用printf,您不需要在格式中指定换行符,而且它似乎仍然可以很好地处理它们。我想知道为什么我的程序集也不处理它们?可能是实现敏感的。我不太熟悉它的“应该”行为。C编译器将\n转换为单个0xA字符。它是编译器中的字符串解析器,而不是printf。反汇编nasm正在生成的内容,也许nasm可以选择像C编译器一样解析,而不是像汇编程序一样解析。