2016-11-17 41 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標籤名稱後省略:

相關問題