Linux NASM обнаруживает EOF - PullRequest
       16

Linux NASM обнаруживает EOF

6 голосов
/ 23 февраля 2012

Я пытаюсь выучить основы asm на linux и не могу найти очень хорошую ссылку. Документы NASM, кажется, предполагают, что вы уже знаете masm ... Я не нашел примеров в документации cmp (за пределами справочника по Intel).

Я написал программу, которая читает один байт из стандартного ввода и записывает его в стандартный вывод. Ниже моя модификация, чтобы попытаться обнаружить EOF на stdin и выйти при достижении EOF. Проблема в том, что он никогда не выходит. Я просто продолжаю печатать последний символ, прочитанный со стандартного ввода. Проблема в моем обнаружении EOF (cmp ecx, EOF) и / или моем переходе к метке _exit (je _exit), я думаю.

Что я делаю не так?

%define EOF     -1

section .bss
        char:   resb    1

section .text
        global  _start

_exit:
        mov     eax,    1       ; exit
        mov     ebx,    0       ; exit status
        int     80h

_start:
        mov     eax,    3       ; sys_read
        mov     ebx,    0       ; stdin
        mov     ecx,    char    ; buffer
        cmp     ecx,    EOF     ; EOF?
        je      _exit
        mov     edx,    1       ; read byte count
        int     80h

        mov     eax,    4       ; sys_write
        mov     ebx,    1       ; stdout
        mov     ecx,    char    ; buffer
        mov     edx,    1       ; write byte count
        int     80h

        jmp     _start

Ради здравомыслия я проверил EOF -1 с этим C:

#include <stdio.h>
int main() { printf("%d\n", EOF); }

1 Ответ

6 голосов
/ 23 февраля 2012

Вы сравниваете адрес буфера с EOF (-1) вместо символа, хранящегося в буфере.

Сказав это, системный вызов read не возвращает значение EOF при достижении конца файла, но возвращает ноль и ничего не помещает в буфер (см. man 2 read).Чтобы определить конец файла, просто проверьте значение eax после вызова read:

section .bss
    buf:   resb    1

section .text
    global  _start

_exit:
    mov     eax,    1       ; exit
    mov     ebx,    0       ; exit status
    int     80h

_start:
    mov     eax,    3       ; sys_read
    mov     ebx,    0       ; stdin
    mov     ecx,    buf    ; buffer
    mov     edx,    1       ; read byte count
    int     80h

    cmp     eax, 0
    je      _exit

    mov     eax,    4       ; sys_write
    mov     ebx,    1       ; stdout
    mov     ecx,    buf    ; buffer
    mov     edx,    1       ; write byte count
    int     80h

    jmp     _start

Если вы хотите правильно сравнить символ с некоторым значением, используйте:

cmp byte [buf], VALUE

Также я переименовал char в buf.char - это базовый тип данных C и неправильный выбор имени переменной.

...