Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux NASM检测EOF_Linux_Assembly_Stdin_Nasm_Eof - Fatal编程技术网

Linux NASM检测EOF

Linux NASM检测EOF,linux,assembly,stdin,nasm,eof,Linux,Assembly,Stdin,Nasm,Eof,我正在尝试学习linux上的asm基础知识,但找不到很好的参考资料。NASM文档似乎假设你已经知道masm。。。我在cmp的文档中没有找到示例(英特尔指令参考之外) 我编写了一个程序,从stdin读取一个字节,然后将其写入stdout。下面是我的修改,尝试在标准输入上检测EOF,并在达到EOF时退出。问题是它永远不会存在。我只是一直在打印从stdin读取的最后一个字符。我认为,问题要么在于我的EOF检测(cmp ecx,EOF)和/或我跳转到\u exit标签(je\u exit) 我做错了什么

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

我编写了一个程序,从stdin读取一个字节,然后将其写入stdout。下面是我的修改,尝试在标准输入上检测EOF,并在达到EOF时退出。问题是它永远不会存在。我只是一直在打印从stdin读取的最后一个字符。我认为,问题要么在于我的EOF检测(
cmp ecx,EOF
)和/或我跳转到
\u exit
标签(
je\u 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); }
#包括
int main(){printf(“%d\n”,EOF);}

您正在将缓冲区的地址与EOF(-1)进行比较,而不是将存储在缓冲区中的字符进行比较

话虽如此,当到达文件末尾时,
read
系统调用不会返回EOF值,但它返回零,并且不会将任何内容粘贴到缓冲区中(请参见
man2 read
)。要确定文件结尾,只需在调用
read
后检查
eax
的值:

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数据类型,对于变量名来说是一个糟糕的选择。

我不熟悉NASM,但是
char
是指向单个字符的指针吗?看起来您可能正在将字符的指针地址与EOF值进行比较。如果是这种情况,则需要取消对指针的引用,然后进行比较。
read
write
系统调用将指向缓冲区的指针作为参数,而不是单个字符。此外,我还将
char
重命名为基本C类型名称以外的名称。我尝试通过
gdb
单步执行程序,
ecx
中的内容似乎从未改变。我似乎保持不变(
0x80490c0
)我在意识到一些事情后更新了我的答案。但是,这是正确的,因为您将缓冲区的地址存储在ecx中,在这种情况下,它存储在内存中的
0x80490c0
sys\u read
调用读取的值存储在该内存位置。即使您更改了缓冲区的内容,它在内存中的位置也保持不变。要取消对指针的引用并将其与另一个字节进行比较,请使用
cmp byte[buf],VALUE