2016-11-17 14 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 0 к string db», он показывает ошибку, но программа работает правильно, печатая все предложение к первое место. К сожалению, я не знаю, что делать с этой информацией. Спасибо за ответ.

+0

Я думаю, 'string' - это переменная, в которой вы храните строку, введенную пользователем. Сколько символов вы ожидаете от входа пользователя? Каков размер переменной 'string'? –

+0

Ну, я не знаю. Предположим, что 20 - максимальное количество символов. Что мне теперь делать? – Zumalo

+3

Тогда вы должны выделить более 1 байт для строки, достаточно для ваших 20 max –

ответ

2

printf("%s", ...) берет на себя ответственность ter arg, но вы передаете ему первые 8 байтов содержимого вашей строки. Используйте mov rsi, string, чтобы получить mov-instant вместо mov rsi, [string] (который является нагрузкой).

(или сохранить 2 кодовых байтов, mov esi, string поскольку статические адреса гарантированно поместился в 32 бита в модели кода по умолчанию.)


Как было отмечено в комментариях, ваш статический буфер слишком мал. Поскольку ваша строка формата не имеет ограничения по размеру, вам нужен буфер бесконечного размера, чтобы избежать риска переполнения длинной строки ввода.

Но давайте сделаем вид, что буфер 1024B достаточно безопасен. Или лучше, используйте %1023s, поэтому гарантировано будет достаточно. Мы не хотим 1024B нулей в нашем исполняемом файле; это было бы глупо. Таким образом, мы должны вместо Оставляем 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.