我试图在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); }
答案 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
重命名为buf
。 char
是基本的C数据类型,是变量名称的错误选择。