Linux NASM检测EOF

时间:2012-02-23 16:46:35

标签: linux assembly stdin nasm eof

我试图在linux上学习基础知识asm,但我找不到很好的参考资料。 NASM文档似乎假设您已经知道masm ...我在cmp的文档中找不到任何示例(在英特尔指令参考之外)。

我编写了一个从stdin读取单个字节并将其写入stdout的程序。下面是我的修改,尝试在stdin上检测EOF并在达到EOF时退出。问题是它永远不会退出。我只是继续打印从stdin读取的最后一个char。问题出在我的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

为了理智,我用这个C验证EOF是-1:

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

1 个答案:

答案 0 :(得分:6)

您正在将缓冲区的地址与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重命名为bufchar是基本的C数据类型,是变量名称的错误选择。