Search code examples
assemblyx86nasmstdoutstdin

Cannot print a number in NASM


I have just started to learn assembly (for a hobby) and I have made this small program that gets a number from the user and prints it out:

section .data:
        message: db "please enter a number: "           ;define message to "please enter a number"
        message_length equ $-message                    ;define message_length to $-message the lenght of the message
        message_done: db "you have entered the number " ;define message_done to "you have entered the number "
        message_done_length equ $-message               ;define message_done_length to the $-message_done the length of message_done
section .bss:
        num resb 5              ;num will store the input the user will give

section .text:
        global _start
_start:
        mov eax, 4              ;set the next syscall to write
        mov ebx, 1              ;set the fd to stdout
        mov ecx, message        ;set the output to message
        mov edx, message_length ;set edx to the length of the message
        int 0x80                ;syscall

        mov eax,3               ;set the next syscall to read
        mov ebx, 2              ;set the fd to stdout
        mov ecx, num            ;set the output to be num
        mov edx, 5              ;set edx to the length of the num
        int 0x80                ;syscall

        mov eax, 4                      ;set the syscall to write
        mov ebx, 1                      ;set the fd to stout
        mov ecx, message_done           ;set the output to the message
        mov edx, message_done_length    ;set edx to the message_done_length
        int 0x80                        ;syscall

        mov eax, 4              ;set the syscall to write
        mov ebx ,1              ;set the fd to stdout
        mov ecx, num            ;set the output to num
        mov edx, 5              ;the length of the message
        int 0x80                ;syscall

        mov eax, 1              ;set the syscall to exit
        mov ebx, 0              ;retrun 0 for sucsess
        int 0x80                ; syscall

When I run this and enter a number followed be enter, I get this:

please enter a number: you have entered the number ����

What am I doing wrong?


Solution

  • Three bugs:

    section .data:
    

    This assembles into a section called .data: which is different from .data. Drop the colon. A section directive is not a label. The same problem occurs in all your other section directives.

    message_done: db "you have entered the number "
    message_done_length equ $-message
    

    Should be $-message_done. As it stands you are writing too many bytes. That is the likely cause of the garbage you see after your message.

            mov eax,3               ;set the next syscall to read
            mov ebx, 2              ;set the fd to stdout
            mov ecx, num            ;set the output to be num
            mov edx, 5              ;set edx to the length of the num
            int 0x80                ;syscall
    

    You want the fd to be stdin (0), your comment says stdout, and file descriptor 2 is actually stderr. Make it mov ebx, 0. It will probably work as is when you run the program from a terminal, because then file descriptors 0, 1 and 2 are all open on the terminal and are all read-write, but it will misbehave if you ever use input redirection.