内容来自于《Intel汇编语言程序设计》(第四版)第11章--------32位Windows编程。
我们的整个顺序应该是,首先将内容写入文件(如果没有文件,将会创建新文件),然后将内容从文件中读出。
首先来看一下将数据写入文件:
TITLE Using WriteFile ( WriteFile.asm )
INCLUDE Irvine32.inc
.data
buffer BYTE "This text is written to an output file.",0dh,0ah
bufSize = ( $ - buffer)
errMsg BYTE "Cannot create file",0dh,0ah,0
filename BYTE "output.txt",0
fileHandle DWORD ? ; handle to output file
bytesWritten DWORD ? ; number of bytes written
.code
main PROC
INVOKE CreateFile,
ADDR filename , GENERIC_WRITE , DO_NOT_SHARE , NULL ,
CREATE_ALWAYS , FILE_ATTRIBUTE_NORMAL , 0
mov fileHandle , eax ; save file handle
.IF eax == INVALID_HANDLE_VALUE
mov edx,OFFSET errMsg ; display error message
call WriteString
jmp QuitNow
.ENDIF
INVOKE WriteFile, ; write text to file
fileHandle, ; file handle
ADDR buffer, ; buffer pointer
bufsize, ; number of bytes to write
ADDR bytesWritten, ; number of bytes written
0 ; overlapped execution flag
INVOKE CloseHandle , fileHandle
QuitNow:
INVOKE ExitProcess,0 ; end program
main ENDP
END main
程序首先使用CreateFile函数打开一个文件:
INVOKE CreateFile,
ADDR filename , GENERIC_WRITE , DO_NOT_SHARE , NULL ,
CREATE_ALWAYS , FILE_ATTRIBUTE_NORMAL , 0
因为这里使用了 CREATE_ALWAYS 标志,所以现存的文件将被覆盖。
后面的代码:
mov fileHandle , eax ; save file handle
.IF eax == INVALID_HANDLE_VALUE
mov edx,OFFSET errMsg ; display error message
call WriteString
jmp QuitNow
.ENDIF
首先将句柄保存到fileHandle 中,然后会判断文件打开是否成功,如果未成功,则会输出一条错误语句之后跳转到QuitNow退出。
如果得到句柄,则程序会使用WriteFile将字符串写入文件:
INVOKE WriteFile, ; write text to file
fileHandle, ; 前面得到的句柄值
ADDR buffer, ; 要输入的字符串的首地址
bufsize, ; 将要写入的数据的长度
ADDR bytesWritten, ; 函数执行完成之后实际写入的数据的byte数,bytesWritten就是返回值
0 ; 异步信息的指针,这个参数是可选的,这里传入0
然后将数据写入文件之后,我们要关闭文件:
INVOKE CloseHandle , fileHandle
这时我们只需要将我们打开的文件的句柄传入即可。
将数据写入文件的代码到这里就结束了。下面来看一下将数据从文件中读取的代码:
TITLE Using ReadFile ( ReadFile.asm )
INCLUDE Irvine32.inc
.data
buffer BYTE 500 DUP(?)
bufSize = ( $ - buffer )
errMsg BYTE "Cannot open file",0dh,0ah,0
filename BYTE "output.txt",0
fileHandle DWORD ? ; handle to output file
byteCount DWORD ? ; number of bytes written
.code
main PROC
INVOKE CreateFile, ; open file for input
ADDR filename , GENERIC_READ,
DO_NOT_SHARE , NULL , OPEN_EXISTING ,
FILE_ATTRIBUTE_NORMAL , 0
mov fileHandle , eax ; save file handle
.IF eax== INVALID_HANDLE_VALUE
mov edx,OFFSET errMsg ; display error message
call WriteString
jmp QuitNow
.ENDIF
INVOKE ReadFile, ; read file into buffer
fileHandle , ADDR buffer ,
bufSize , ADDR byteCount , 0
INVOKE CloseHandle, ; close the file
fileHandle
mov esi , byteCount ; insert null terminator
mov buffer[esi] , 0 ; into buffer
mov edx,OFFSET buffer ; display the buffer
call WriteString
QuitNow:
INVOKE ExitProcess , 0 ; end program
main ENDP
END main
程序首先仍然使用CreateFile打开将要读取数据的文件,这里使用了OPEN_EXISTING 参数。之后同样把eax中的句柄保存到变量中。然后调用ReadFile函数,将句柄参数传入,然后将数据读取到缓冲区buffer中,之后将文件句柄关闭。
之后的程序如下:
mov esi , byteCount ; 首先将调用ReadFile返回的字节数byteCount赋值到esi中
mov buffer[esi] , 0 ; 这样就取到了buffer的最后一个元素的地址,因为是字符串的结束,所以将0赋给最后一个元素。
mov edx,OFFSET buffer ; 将buffer的偏移地址赋值到edx中
call WriteString ; 打印出buffer缓冲区中的数据内容
读取文件代码结束。