问题
Hi I'm trying to write some assembly code that uses printf to print a given string. I am declaring my strings before use in the .data section and a test example looks as follows:
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
I'm then compiling as follows:
nasm -f elf64 test.asm; gcc -m64 -o test test.o
And finally running:
./test
My output is as follows:
Hello\nWorld\n
I really don't want to split sentence0 up into the following:
sentence0: db "Hello", 10, 0
sentence1: db "World", 10, 0
and then call the print twice. Is there a better way to do it?
Thanks in advance!
回答1:
NASM accepts strings in single quotes ('...'
) or double quotes ("..."
), which are equivalent, and do not provide any escapes; or in backquotes (`...`
), which provide support for C-style escapes, which is what you want.
(See section 3.4.2, "Character Strings", in the documentation.)
To get actual ASCII newlines in your data in memory, rather than literal backslash n:
sentence0: db `Hello\nWorld\n`, 0
Or do it manually:
sentence0: db 'Hello', 10, 'World`, 10, 0
YASM (another NASM-syntax assembler) doesn't accept backticks, so the manual option is your only choice there.
And BTW, you can call puts
instead of printf
if you don't have any actual formatting in your format string (leave out the trailing newline).
回答2:
You have the newlines (\n) in the string to be output. They should be in the format string to be treated as newlines. This solves half of your problem:
outputstringfmt: db "%s\n%s\n", 0
sentence0: db "Hello", 0
sentence1: db "World", 0
And something like this should print newlines after each word:
outputstringfmt: db "%s", 0
sentence0: db "Hello", 10 , "World", 10 , 0
来源:https://stackoverflow.com/questions/8533408/printing-new-lines-with-printf-assembly