简体   繁体   English

NASM-printf不打印第一个字符

[英]NASM - printf doesn't print the first character

I want to write a program which returns the string you write. 我想编写一个返回您编写的字符串的程序。 But it always prints it without the first character. 但是它始终打印时不带第一个字符。 Also, it doesn't return anything past the first space. 此外,它不会返回超过第一个空格的任何内容。

Example: 例:

IN: test
OUT: est

Code: 码:

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

I noticed that if I change string db 0 to string db ", it shows an error, but the program works correctly, printing the entire sentence to the first space. Unfortunately I don't have any clue what to do with that info. Thanks for the answer. 我注意到,如果我将string db 0更改为string db “,则显示错误,但程序正常运行,将整个句子打印到第一个空格。不幸的是,我不知道该信息的处理方法。谢谢寻找答案。

printf("%s", ...) takes a pointer arg, but you're passing it the first 8 bytes of the contents of your string. printf("%s", ...)使用指针arg,但您正在向其传递字符串内容的前8个字节。 Use mov rsi, string to get a mov-immediate instead of mov rsi, [string] (which is a load). 使用mov rsi, string获得立即移动,而不是mov rsi, [string] (这是负载)。

(Or to save 2 code bytes, mov esi, string since static addresses are guaranteed to fit in 32 bits in the default code model.) (或者保存2个代码字节mov esi, string因为在默认代码模型中保证静态地址可以容纳32位。)


As pointed out in comments, your static buffer is too small. 正如评论中指出的那样,您的静态缓冲区太小。 Since your format string has no size limit, you need an infinite-size buffer to avoid any risk of a long input line overflowing it. 由于您的格式字符串没有大小限制,因此您需要一个无限大小的缓冲区,以避免任何长输入行将其溢出的风险。

But let's pretend that a 1024B buffer is safe enough. 但是,让我们假设1024B缓冲区足够安全。 Or better, use %1023s so it is guaranteed to be enough. 或更好,请使用%1023s ,以确保足够。 We don't want 1024B of zeros in our executable; 我们不希望在可执行文件中包含1024B的零。 that would be silly. 那真是愚蠢。 So we should instead reserve 1024B in the BSS: 因此,我们应该在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

There's no reason to omit the : after label names on data, and good reason not to . 没有理由在数据上的标签名后省略: ,而没有理由

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM