问题
I have the following code that prints the number of parameters passed to ./main
. Notice the fmt
in the rodata
section. I've included the new line \n
, just like in C, but instead of printing the new line, it prints:
Number of parameters: 1 \n
My code is:
;main.asm
GLOBAL main
EXTERN printf
section .rodata:
fmt db "Number of parameters: %d \n", 0
section .text:
main:
push ebp
mov ebp, esp ;stackframe
push dword[ebp+8] ;prepara los parametros para printf
push fmt
call printf
add esp, 2*4
mov eax, 0 ;return value
leave ;desarmado del stack frame
ret
I know that including a 10 before the 0 and after the "Number..." in fmt
will print it, but I want printf
to do it. I assemble the code with NASM and then link it via GCC to create my executable.
回答1:
When you use quotes or double quotes around a string in NASM, it doesn't accept C style escape sequences. On Linux you can encode \n
as ASCII 10 like this:
fmt db "Number of parameters: %d", 10, 0
There is an alternative. NASM supports backquotes (backticks) which will allow NASM to process the characters between them as C style escape sequences. This should work as well:
fmt db `Number of parameters: %d \n`, 0
Please note: Those are not single quotes, but backticks. This is described in the NASM documentation:
3.4.2 Character Strings
A character string consists of up to eight characters enclosed in either single quotes ('...'), double quotes ("...") or backquotes (
...
). Single or double quotes are equivalent to NASM (except of course that surrounding the constant with single quotes allows double quotes to appear within it and vice versa); the contents of those are represented verbatim. Strings enclosed in backquotes support C-style -escapes for special characters.
回答2:
The assembler is not C. The C compiler understands \n as an escape code for ASCII 10. The assembler does not and treats it as two characters. Add the 10 as you describe.
来源:https://stackoverflow.com/questions/36707877/assembly-printf-not-printing-new-line