NASM - printf 不打印第一个字符

NASM - printf doesn't print the first character

我想编写一个程序,其中 return 是您编写的字符串。但它总是在没有第一个字符的情况下打印它。此外,它不会 return 任何超过第一个 space.

的东西

示例:

IN: test
OUT: est

代码:

extern printf, scanf, exit
global main

section .text
main:
    push rbp
                            ;input of string
    mov rdi, format
    mov rsi, string
    mov rax, 0
    call scanf

                            ;output of string
    mov rdi, format_out
    mov rsi, qword [string]
    mov rax, 0
    call printf
_exit:                        ;end of program
    pop rbp
    call exit

section .data
  format     db "%s", 0
  string     db 0
  format_out db "You wrote: %s", 0

我注意到,如果我将 string db 0 更改为 string db",它会显示错误,但程序运行正常,将整个句子打印到第一个 space。不幸的是我不知道如何处理该信息。感谢您的回答。

printf("%s", ...) 接受一个指针 arg,但您将字符串内容的前 8 个字节传递给它。使用 mov rsi, string 获取 mov-immediate 而不是 mov rsi, [string] (这是一个负载)。

(或者为了节省 2 个代码字节,mov esi, string 因为在默认代码模型中静态地址保证适合 32 位。)


正如评论中指出的,您的静态缓冲区太小。由于您的格式字符串没有大小限制,因此您需要一个无限大小的缓冲区以避免长输入行溢出它的任何风险。

但我们假设 1024B 缓冲区足够安全。或者更好,使用 %1023s 以确保足够。我们不希望我们的可执行文件中有 1024B 个零;那将是愚蠢的。所以我们应该在 BSS 中保留 1024B:

section .rodata
  format:     db "%1023s", 0         # actually set a size limit, leaving room for the [=10=]
  format_out: db "You wrote: %s", 0

section .bss
  string:     resb 1024              # RESERVE 1024 bytes.  Only works in .bss

没有理由省略数据标签名称后的 :good reason not to.