我正在尝试学习 Linux 上的 asm 基础知识,但我找不到很好的引用资料。 NASM 文档似乎假定您已经知道 masm...我在 cmp
的文档中没有找到示例(在 Intel 指令引用之外)。
我编写了一个程序,从标准输入读取单个字节并将其写入标准输出。下面是我尝试检测标准输入上的 EOF 并在达到 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
为了理智起见,我用这个 C: 验证了 EOF 是 -1
#include <stdio.h>
int main() { printf("%d\n", EOF); }
最佳答案
您正在将缓冲区的地址与 EOF (-1) 而不是存储在缓冲区中的字符进行比较。
话虽如此,当到达文件末尾时,read
系统调用不会返回 EOF 的值,但它会返回零并且不会在缓冲区中保留任何内容(请参阅 男人 2 阅读
)。要识别文件结尾,只需在调用 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 数据类型,不适合作为变量名。
关于Linux NASM 检测 EOF,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9417341/