Не удается напечатать номер в NASM

#nasm #stdout #write

Вопрос:

Я только начал изучать ассемблер (для хобби), и я создал эту небольшую программу, которая получает номер от пользователя и распечатывает его:

 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

 

Когда я запускаю это, ввожу номер и нажимаю enter, я получаю это:

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

Я делаю что-то не так?

Ответ №1:

Три ошибки:

 section .data:
 

Это собирается в раздел под названием .data: , который отличается от .data . Отбросьте двоеточие. Директива раздела — это не метка. Та же проблема возникает во всех ваших других section директивах.

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

Должно быть $-message_done . В нынешнем виде вы пишете слишком много байтов. Это вероятная причина мусора, который вы видите после своего сообщения.

         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
 

Вы хотите, чтобы fd был stdin (0), в вашем комментарии указано stdout, а файловый дескриптор 2 на самом деле является stderr. Сделай это mov ebx, 0 . Вероятно, это будет работать так же, как и при запуске программы с терминала, потому что тогда файловые дескрипторы 0, 1 и 2 все открыты на терминале и все доступны для чтения и записи, но это будет неправильно, если вы когда-либо используете перенаправление ввода.