x86 Assembler using MASM32 Tutorial 7 - Create and Write to Files



Watch the video or follow the tutorial.



In this, tutorial 7 we will have a little look at creating and writing to files. We will create a text file using Windows API and then write data to the file again using Windows API. So, first of all open Visual MASM, if you haven't installed Visual MASM yet you can learn how to do it here. Once installed open it and learn create the default code template needed for all my tutorials here. This default code will be the starting point for most of our tutorials including this one. So, once all this is done you should be looking at the code window as seen below:


Scroll down until you see the .data section and add the following code:

openError DB "Error Creating File", 0
fileName DB "D:\Temp\File.txt", 0
errorCaption DB "Error", 0
txtString DB "123456789", 0
len1 Equ $ - txtString
successCaption DB "Success", 0
successText DB "Data written successfully", 0



Then scroll down to the uninitialised data section which starts with .data? and add the following code:

fhandle DD ?
bytesWritten DD ?

Then scroll down until you see the .code section and underneath the label start: and add the following code:

; CreateFile Function, Fails if FIle Exists
Push 0
Push FILE_ATTRIBUTE_NORMAL
Push CREATE_NEW
Push 0
Push 0
Push GENERIC_READ + GENERIC_WRITE
Push Offset fileName
Call CreateFile

Mov fhandle, Eax

Cmp Eax, 0FFFFFFFFh

Jnz file_created

; If Error Previous Jump Ignored and Now We Declare Error With a MessageBox
Push MB_OK
Push Offset errorCaption
Push Offset openError
Push 0
Call MessageBox

Jmp end_

file_created:

Push 0
Push Offset bytesWritten
Push len1
Push Offset txtString
Push fhandle
Call WriteFile

; Show WriteFile Successful
Push MB_OK
Push Offset successCaption
Push Offset successText
Push 0
Call MessageBox

Push fhandle
Call CloseHandle

end_:

The first function call is to CreateFile which creates a file at the location named in the fileName variable. On my computer the location is D:\Temp so you should change this line to whatever location you have access to on your computer. The file name is not so important just make sure that no file with that name at that location already exists or an error will occur. After the CreatfIle function is complete the contents of the Eax register is loaded into the fhandle variable. If the CreateFile function was successful then the Eax register will hold the memory address of the handle to the created file, if not it will hold an error code. The compare command tests to see the Eax register holds the error code and if it doesn't the jump if not zero command takes us the part of the code that should run if the file is ready to be written to. If the Eax register does hold an error code then a message box is displayed reporting the error and the program ends.

If the file is ready to be written to then we write the txtStrign variable to the file using the WriteFile command, a message box is displayed telling us it was successful and the program ends. We can then open the file on our hard drive and check if the text has indeed been written. It should look as below:



As you can see the program was successful. The entire code looks like this:

; *************************************************************************
; 32-bit Windows Program
; *************************************************************************

.686                                      ; Enable 80686+ instruction set
.model flat, stdcall                ; Flat, 32-bit memory model (not used in 64-bit)
option casemap: none         ; Case sensitive syntax

; *************************************************************************
; MASM32 proto types for Win32 functions and structures
; *************************************************************************
include c:\masm32\include\windows.inc
include c:\masm32\include\user32.inc
include c:\masm32\include\kernel32.inc
include c:\masm32\include\masm32rt.inc     ; for using ustr$() and such like

; *************************************************************************
; MASM32 object libraries
; *************************************************************************
includelib c:\masm32\lib\user32.lib
includelib c:\masm32\lib\kernel32.lib

; *************************************************************************
; Our data section.
; *************************************************************************
.data

openError DB "Error Creating File", 0
fileName DB "D:\Temp\File.txt", 0
errorCaption DB "Error", 0
txtString DB "123456789", 0
len1 Equ $ - txtString
successCaption DB "Success", 0
successText DB "Data written successfully", 0

; *************************************************************************
; Our unintialised data section.
; *************************************************************************
.data?

fhandle DD ?
bytesWritten DD ?

; *************************************************************************
; Our constant section.
; *************************************************************************
.const



; *************************************************************************
; Macros
; *************************************************************************



; *************************************************************************
; Our executable assembly code starts here in the .code section
; *************************************************************************
.code

start:

; CreateFile Function, Fails if FIle Exists
Push 0
Push FILE_ATTRIBUTE_NORMAL
Push CREATE_NEW
Push 0
Push 0
Push GENERIC_READ + GENERIC_WRITE
Push Offset fileName
Call CreateFile

Mov fhandle, Eax

Cmp Eax, 0FFFFFFFFh

Jnz file_created

; If Error Previous Jump Ignored and Now We Declare Error With a MessageBox
Push MB_OK
Push Offset errorCaption
Push Offset openError
Push 0
Call MessageBox

Jmp end_

file_created:

Push 0
Push Offset bytesWritten
Push len1
Push Offset txtString
Push fhandle
Call WriteFile

; Show WriteFile Successful
Push MB_OK
Push Offset successCaption
Push Offset successText
Push 0
Call MessageBox

Push fhandle
Call CloseHandle

end_:

; Exit App
Push 0
Call ExitProcess

end start


Thank you for following this tutorial, I hope you found it useful. In the next tutorial we will read from existing files using other Windows APIs, so until then, enjoy.

Link to a text file with complete source code and more comments - here.