2016-11-17 1 views
-1

Je veux écrire un programme qui retourne la chaîne que vous écrivez. Mais il l'imprime toujours sans le premier caractère. En outre, il ne renvoie rien après le premier espace.NASM - printf n'imprime pas le premier caractère

Exemple:

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 

J'ai remarqué que si je change string db 0-string db », il montre une erreur, mais le programme fonctionne correctement, l'impression de la phrase entière à la Malheureusement, je n'ai aucune idée de ce qu'il faut faire avec cette info.Merci de la réponse

+0

Je suppose que 'string' est la variable où vous stockez la chaîne entrée par l'utilisateur. Combien de caractères attendez-vous que l'utilisateur entre? Quelle est la taille de la variable 'string'? –

+0

Eh bien, je ne sais pas. Disons que 20 est le nombre maximum de caractères. Qu'est-ce que je fais maintenant? – Zumalo

+3

Ensuite, vous devez allouer plus de 1 octet pour la chaîne, assez pour votre 20 max –

Répondre

2

printf("%s", ...) prend un point ter arg, mais vous lui passez les 8 premiers octets du contenu de votre chaîne. Utilisez mov rsi, string pour obtenir un mov-immédiat au lieu de mov rsi, [string] (qui est une charge).

(Ou pour sauver 2 octets de code, mov esi, string puisque les adresses statiques sont garantis pour tenir dans 32 bits dans le modèle de code par défaut.)


Comme indiqué dans les commentaires, votre tampon statique est trop petit. Comme votre chaîne de format n'a pas de limite de taille, vous avez besoin d'un tampon de taille infinie pour éviter tout risque de débordement d'une longue ligne d'entrée.

Mais supposons qu'un tampon 1024B soit suffisamment sûr. Ou mieux, utilisez %1023s afin qu'il soit garanti d'être suffisant. Nous ne voulons pas 1024B de zéros dans notre exécutable; ce serait idiot. Donc, nous devrions plutôt réserver 1024B dans le 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 

Il n'y a aucune raison d'omettre le : après les noms d'étiquettes sur les données et good reason not to.