2016-11-17 35 views
-1

我想编写一个程序,它返回你写的字符串。但它总是打印它没有第一个字符。此外,它不会返回任何超过第一空间的东西。NASM - printf的不打印的第一个字符

例子:

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 0string db”,它显示了一个错误,但该程序正常工作,打印整个句子的第一空间。不幸的是,我没有任何线索如何处理这些信息。感谢您的回答。

+0

我想'string'是存储用户输入的字符串变量。你期望用户输入多少个字符?变量'string'的大小是多少? –

+0

我不知道。假设20是最大字符数。现在我该怎么做? – Zumalo

+3

那么你应该分配超过1个字节的字符串,足以让你的最高20 –

回答

2

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

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


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

但是,让我们假装一个1024B缓冲区是足够安全的。或者更好的是,使用%1023s,这样保证足够。我们的可执行文件中不需要1024B的零;那会很愚蠢。因此,我们应该将保留1024B在BSS:

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标签名称后省略:

相关问题