Assembly 无法读取文件的内容
我正在尝试学习汇编语言,到目前为止,我只使用了c或java等高级语言。 我回顾了去年在c语言中的一些任务,其中一个任务是制作一个命令行刽子手游戏,所以我想我会尝试在汇编中实现它。我试图读取一个.txt文件,但似乎无法正常工作。出于测试目的,我只想直接将文件打印到终端,但由于某些原因,sys_读取失败 代码如下:Assembly 无法读取文件的内容,assembly,nasm,Assembly,Nasm,我正在尝试学习汇编语言,到目前为止,我只使用了c或java等高级语言。 我回顾了去年在c语言中的一些任务,其中一个任务是制作一个命令行刽子手游戏,所以我想我会尝试在汇编中实现它。我试图读取一个.txt文件,但似乎无法正常工作。出于测试目的,我只想直接将文件打印到终端,但由于某些原因,sys_读取失败 代码如下: SYS_EXIT equ 1 ; UNIX system call sys_exit SYS_READ equ 3
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
我不知道我做错了什么,我对组装还是很陌生。
谢谢您的帮助。您应该学会使用调试器,这样您就可以修复自己的错误。但是,在这种情况下,打印的错误消息准确地指出了问题的位置,因此您可以在头脑中进行操作,即使只需重新阅读您自己的评论:
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\u words
的代码块
长话短说:你可能想要
jnzsplit_单词
而不是jzsplit_单词
。从长远来看,您可能需要多次read
调用来重复填充缓冲区。如果为其提供文件的完整路径,会发生什么情况?