2014-05-20 138 views
0

我想學習大會,到目前爲止,我只使用像c或java這樣的高級語言。 我回顧了去年在c中的一些作業,其中一個是製作命令行hang子手遊戲,所以我認爲我會嘗試在程序集中實現這一點。我正在嘗試讀取.txt文件,但似乎沒有讓它正常工作。出於測試目的,我只是想直接將文件打印到終端,但由於某種原因,sys_read失敗。無法讀取文件的內容

下面是代碼:

SYS_EXIT equ 1       ; UNIX system call sys_exit 
SYS_READ equ 3       ; UNIX System call sys_read 
SYS_WRITE equ 4       ; UNIX System call sys_write 
SYS_OPEN equ 5       ; UNIX System call sys_open 

STDIN equ 0        ; File descriptor for Standard in stream 
STDOUT equ 1       ; File descriptor for Standard out stream 

; print to standard out macro 
    %macro print 2 
     pushad       ; Save all regisers 
     mov eax, SYS_WRITE    ; Write system call 
     mov ebx, STDOUT     ; File descriptor for stdout 
     mov ecx, %1      ; Message to print as argument 1 
     mov edx, %2      ; Message length as argument 2 
     int 0x80      ; Call kernel 
     popad       ; restore all registers 
    %endmacro 

; print string to standard out macro 
    %macro print_str 1 
     section .data 
      %%str db %1     ; adress to hold string 
      %%strL equ $ - %%str  ; length of string 
     section .text 
      print %%str, %%strL   ; print string to stdout using print macro 
    %endmacro 

; print newline 
    %macro println 0   
     section .data   
      %%strln db 0xA, 0xD   ; adress to hold newline and carrige return 
     section .text 
      print %%strln, 2   ; print newline 
    %endmacro 

; print string with trailing newline 
    %macro print_str_ln 1 
     section .data 
      %%str db %1     ; adress to hold string 
      %%strL equ $ - %%str  ; length of string 
     section .text 
      print %%str, %%strL   ; print string to stdout using print macro 
      println      ; prints newline 
    %endmacro 

; exit program 
    %macro exit 1 
     mov eax, SYS_EXIT    ; Exit system call 
     mov ebx, $1      ; Return value 
     int 0x80      ; call kernel 
    %endmacro 

section .text 
    global _start      ; Required for linker (ld) 
_start:         ; Linker entry point 
    print_str_ln "Welcome to hangman" ; print message to user 
    println        ; print newline 
    call open_file      ; open file and read 
    exit 0        ; exit program 

; Open the words list file 
open_file: 
    mov eax, SYS_OPEN     ; System call open 
    mov ebx, word_source_file   ; Points to filepath 
    xor ecx, ecx      ; O_RDONLY 
    xor edx, edx      ; mode is ignored when O_CREATE isn't specified 
    int 0x80       ; call kernel 
    test eax, eax      ; check output of SYS_OPEN 
    jns read_file      ; If sign flag set, read file 
    print_str_ln "Could not open file" ; Print error message to user 
    exit 1        ; exit program 

; read the file that was opened 
read_file: 
    mov ebx, eax      ; move file descriptor from eax to ebx 
    mov eax, SYS_READ     ; system call SYS_READ 
    mov ecx, buffer      ; The buffer 
    mov edx, bufferlen     ; The length of the buffer 
    int 0x80       ; call kernel 
    test eax, eax      ; check for errors 
    jz split_words      ; If EOF return 
    print_str_ln "Counld not read file" ; Print error message 
    js exit 1       ; If read faild exit 

; TESTING - Print contentsof buffer 
split_words: 
    mov edx, eax      ; The amount of bytes read, returned from sys_read 
    mov eax, SYS_WRITE     ; System call sys_write 
    mov ebx, STDOUT      ; File descriptor (stdout) 
    mov ecx, buffer      ; The buffer 
    int 0x80       ; call kernel 
    ret         ; return 


section .bss 
    buffer resb 2048     ; A 2kb buffer ussed to read 

section .data 
bufferlen dw 2048      ; The length of buffer 
newline db 0xA, 0xD      ; Newline and carrige return 
word_source_file db 'words.txt', 0  ; The path to the words file 

現在,當我使用匯編器和鏈接和運行我得到:

$ nasm -f elf hangman.asm 
$ ld -m elf_i386 -o hangman hangman.o 
$ ./hangman 
Welcome to hangman 

Counld not read file 

我不知道我做錯了,我組裝仍然很新。 謝謝你的幫助。

+0

如果你給它的文件的完整路徑會發生什麼? – user3344003

回答

1

您應該學會使用調試器,以便您可以修復自己的錯誤。然而,在這種情況下,印刷錯誤信息準確查明問題的位置,所以你甚至可以只是重新閱讀自己的評論做在你的腦袋:

test eax, eax      ; check for errors 
jz split_words      ; If EOF return 
print_str_ln "Counld not read file" ; Print error message 
js exit 1       ; If read faild exit 

顯然導致了其他的東西比零讀你考慮一個錯誤。這不是錯誤,系統調用返回讀取的字節數。但當然,您已經知道,給定代碼塊split_words

長話短說:你可能想要jnz split_words而不是jz split_words。從長遠來看,您可能需要多次調用read來重複填充緩衝區。