2012-02-23 70 views
4

我想学习Linux上的基本asm,我找不到很好的参考。 NASM文档似乎假设您已经知道masm ...我没有在cmp(英特尔指令参考之外)的文档中找到示例。Linux NASM检测EOF

我写了一个程序,它从标准输入读取一个字节并将其写入标准输出。下面是我尝试在stdin上检测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 

对于理智的缘故,我验证EOF是-1,这个C:

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

我对NASM并不熟悉,但'char'是指向单个字符的指针吗?看起来你可能会比较字符的指针地址和EOF值。如果是这种情况,则需要取消引用指针然后进行比较。 'read'和'write'系统调用将指针指向缓冲区作为参数,而不是单个字符。另外,我会将'char'重命名为非基本C类名称。 – 2012-02-23 16:53:25

回答

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 

另外,我已更名为charbufchar是一个基本的C数据类型,也是变量名称的错误选择。

+0

我试着通过'gdb'浏览程序,'ecx'中的内容似乎永远不会改变。我似乎保持不变('0x80490c0') – tMC 2012-02-23 18:42:43

+2

我意识到一些事情后更新了我的答案。但是,这是正确的,因为您将缓冲区的地址存储在ecx中,该地址在0x80490c0处存储在内存中。由'sys_read'调用读入的值被存储在那个内存位置。即使您更改缓冲区的内容,其在内存中的位置仍然相同。要取消引用指针并将其与另一个字节进行比较,请使用'cmp byte [buf],VALUE'。 – 2012-02-23 18:48:57