2012-02-23 61 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