Я пытаюсь научиться писать ассемблер на X86 на NASM. Я пытаюсь написать программу, которая принимает одно целое значение и выводит его обратно на стандартный вывод перед выходом.

Мой код:

section .data
        prompt: db "Enter a number: ", 0
        str_length: equ $ - prompt

section .bss
        the_number: resw 1

section .text

global _start

_start:
        mov eax, 4      ; pass sys_write
        mov ebx, 1      ; pass stdout
        mov edx, str_length     ; pass number of bytes for prompt
        mov ecx, prompt     ; pass prompt string
        int 80h
        
        mov eax, 3      ; sys_read
        mov ebx, 0      ; stdin
        mov edx, 1      ; number of bytes
        mov ecx, [the_number]       ; pass input of the_number
        int 80h
        
        mov eax, 4
        mov ebx, 1
        mov edx, 1
        mov ecx, [the_number]
        int 80h
        
        mov eax, 1          ; exit
        mov ebx, 0          ; status 0
        int 80h

Оттуда я собираю nasm -felf -o input.o input.asm и связываю ld -m elf_i386 -o input input.o.

Я запускаю тест и ввожу целое число, и когда я нажимаю ввод, программа завершается, и Bash пытается выполнить ввод числа как команду. Я даже echo присвоил статус выхода и получил 0.

Так что это странное поведение.

0
Sean 7 Сен 2020 в 09:15

1 ответ

Лучший ответ

Вызов чтения завершается с ошибкой и не считывает ввод. Когда ваша программа завершается, этот ввод все еще ожидает считывания на TTY (который был стандартным вводом этой программы), и в этот момент bash его считывает.

Вы должны проверить статус возврата ваших системных вызовов. Если при возврате системного вызова EAX является отрицательным числом, это код ошибки. Например, в этом случае EAX содержит -14, что означает EFAULT («Плохой адрес»).

Причина сбоя чтения заключается в том, что вы передаете недопустимый указатель в качестве адреса буфера. Вам нужно загрузить адрес the_number, а не его значение. Используйте mov ecx, the_number.

3
Peter Cordes 8 Сен 2020 в 05:24