NASM - printf不会打印第一个字符

时间:2016-11-17 21:55:19

标签: assembly printf nasm x86-64

我想写一个程序,它返回你写的字符串。但它总是在没有第一个字符的情况下打印它。此外,它不会返回通过第一个空格的任何内容。

示例:

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“,则显示错误,但程序正常工作,将整个句子打印到第一个空格。不幸的是我没有任何线索如何处理该信息。感谢您的回答。

1 个答案:

答案 0 :(得分:2)

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 \0
  format_out: db "You wrote: %s", 0

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

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