News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Read and Writing files

Started by krikara, November 02, 2010, 02:53:24 AM

Previous topic - Next topic

krikara

Hello, I was looking through the projects from Kip Irvine in chapter 11 and he gives two procedures, one for reading files and one for writing files.
I was wondering how I can somehow combine the two inorder to create one program that will read an input file, alter the input, and then output to a new file.

Here, though, I just want to know how to combine the two programs so I can read the input file (input.txt, create a new file called output.txt and paste the input into that file.

TITLE Reading a File                      (ReadFile.asm)

; Opens, reads, and displays a text file using
; procedures from Irvine32.lib.

INCLUDE Irvine32.inc
INCLUDE macros.inc

BUFFER_SIZE = 50

.data
buffer BYTE BUFFER_SIZE DUP(?)
filename    BYTE 80 DUP(0)
fileHandle  HANDLE ?

.code
main PROC

; Let user input a filename.
mWrite "Enter an input filename: "
mov edx,OFFSET filename
mov ecx,SIZEOF filename
call ReadString

; Open the file for input.
mov edx,OFFSET filename
call OpenInputFile
mov fileHandle,eax

; Check for errors.
cmp eax,INVALID_HANDLE_VALUE ; error opening file?
jne file_ok ; no: skip
mWrite <"Cannot open file",0dh,0ah>
jmp quit ; and quit
file_ok:

; Read the file into a buffer.
mov edx,OFFSET buffer
mov ecx,BUFFER_SIZE
call ReadFromFile
jnc check_buffer_size ; error reading?
mWrite "Error reading file. " ; yes: show error message
call WriteWindowsMsg
jmp close_file

check_buffer_size:
cmp eax,BUFFER_SIZE ; buffer large enough?
jb buf_size_ok ; yes
mWrite <"Error: Buffer too small for the file",0dh,0ah>
jmp quit ; and quit

buf_size_ok:
mov buffer[eax],0 ; insert null terminator
mWrite "File size: "
call WriteDec ; display file size
call Crlf

; Display the buffer.
mWrite <"Buffer:",0dh,0ah,0dh,0ah>
mov edx,OFFSET buffer ; display the buffer
call WriteString
call Crlf

close_file:
mov eax,fileHandle
call CloseFile


quit:
exit
main ENDP

END main



TITLE Creating a File (CreateFile.asm)

; Inputs text from the user, writes the text to an output file.

INCLUDE Irvine32.inc 

BUFFER_SIZE = 501
.data
buffer BYTE BUFFER_SIZE DUP(?)
filename     BYTE "output.txt",0
fileHandle   HANDLE ?
stringLength DWORD ?
bytesWritten DWORD ?
str1 BYTE "Cannot create file",0dh,0ah,0
str2 BYTE "Bytes written to file [output.txt]: ",0
str3 BYTE "Enter up to 500 characters and press "
     BYTE "[Enter]: ",0dh,0ah,0

.code
main PROC
; Create a new text file.
mov edx,OFFSET filename
call CreateOutputFile
mov fileHandle,eax

; Check for errors.
cmp eax, INVALID_HANDLE_VALUE ; error found?
jne file_ok ; no: skip
mov edx,OFFSET str1 ; display error
call WriteString
jmp quit
file_ok:

; Ask the user to input a string.
mov edx,OFFSET str3 ; "Enter up to ...."
call WriteString
mov ecx,BUFFER_SIZE ; Input a string
mov edx,OFFSET buffer
call ReadString
mov stringLength,eax ; counts chars entered

; Write the buffer to the output file.
mov eax,fileHandle
mov edx,OFFSET buffer
mov ecx,stringLength
call WriteToFile
mov bytesWritten,eax ; save return value
call CloseFile

; Display the return value.
mov edx,OFFSET str2 ; "Bytes written"
call WriteString
mov eax,bytesWritten
call WriteDec
call Crlf

quit:
exit
main ENDP
END main


I noticed that both programs used buffer with different buffer sizes, so I don't understand how I can read and then create a new output file when the buffer sizes are different.

dedndave

without seeing the rest of the code, i am guessing...
but, you may read 50 bytes into the buffer several times, each time overwriting the old data
you might make reads on the input file many times to collect small bits of information
when it comes time to write, you may be able to write the entire outpur file all at once - or in fewer passes

oh - welcome to the forum   :U

krikara

Quote from: dedndave on November 02, 2010, 02:59:37 AM
without seeing the rest of the code, i am guessing...
but, you may read 50 bytes into the buffer several times, each time overwriting the old data
you might make reads on the input file many times to collect small bits of information
when it comes time to write, you may be able to write the entire outpur file all at once - or in fewer passes

oh - welcome to the forum   :U

If the input buffer size is 50 , and the output buffer size is 501, then isn't the input always going to be smaller than the output? That would mean I don't have to overwrite anything?
Would it just make more sense to make the buffersize 501 universal or does it affect the input function? I'm new to assembly and don't really understand all the coding that well.

dedndave

again, without seeing the entire program, i don't know what is going on - lol
but, Kip is a pretty sharp guy - i am sure he has his reasons
i don't know the sizes of the input or output files

in some applications, you can use the same buffer for reading and writing
in practice, you can make these buffers considerably larger
computers, these days, have a lot of memory to work with

but, each program is written to meet the needs of the application
there must be some reason that Kip chose those sizes

krikara

Okay so far I combined the two programs, but I have still yet to make the input turn into the out put.

dedndave

well - we can't diagnose what we can't see - lol
attach your combined program to your next post
you can do that by ZIP'ing it and using the Additional Options underneath the reply window to attach

krikara

Is it better to post code with the code quotes on here  or to zip it up and upload it?

Anyways, this is what I got done so far. I managed to combine the two programs to run successfully, however I cannot manage to make the program output what it read in the input file.

The program stores the input buffer into edx , then i used mov ebx,edx

and then later I do mov edx,ebx thinking it saved the input, but it didn't :(

----------------------------------------
What am I doing wrong?

Thanks

dedndave

well - we usually post entire programs zipped
small snippets get posted literally

give me a while to look it over   :bg

dedndave

yes - you stored the offset of the buffer text in EBX
however, that register probably gets used for other things, so your value gets trashed
but you don't have to store it in a register
in fact, you don't have to store it at all
you should be able to get the address into EDX again by using
        mov     edx,offset buffer
i see you have that line of code, but it is commented out
i can't test the code, as i do not have Kip's 32-bit library and macro files
i can't really verify how the modules are used, either, as i don't have the docs - lol
but, i assume you used them the same way he did in his example programs

dedndave

btw - what is the result you did get...

did it display the contents of the input file ?
did you get an error message ?
did it create a 0-length output file ?

krikara

For the zip file I uploaded, it outputted nothing lol.

Alright, I will try to uncomment your suggestion and see if it works!

edit: okay so uncommenting the mov edx offset buffer did not work (and deleting the mov edx,ebx part).

I think it is because after I stored the input into edx, I used edx again later for other purposes. What I don't understand is why ebx didn't store the buffer the first time around because
ebx was never used again after. Anyways, would Call CloseFile after I read the input file affect it? I am going to try deleting that and see what happens if I never close the input file.

EDIT2: Okay so I called DumpRegs after I read the input from the input file and I called DumpRegs before I outputted and the EDX values happened to be the same. I think this means that something is wrong with writing my EDX to the output file. The original program asked the user to type input and it would output it to output.txt. I'm not sure how if I need a different method , and if so, I have no idea what is wrong :/

dedndave

well - let's start at the beginning
if it didn't display the text, then the problem is earlier on...

i.e. it either didn't read the file, or it isn't where you think it should be - er sumpin

at this point, we do not know if the value was successfully saved in EBX

you may have to write a little debugging code
(or step through it with a debugger - setting that up is a little complicated)

can you successfully display a value ?
if so, you can see what values the registers are holding

krikara

Okay, it did successfully read the input because it printed that in command prompt. And I called dump regs to see the value of edx. Right before I outputted edx, i called dumpregs again and the value of edx was the same, so I am pretty sure something is wrong with the outputting part.

krikara

this is what command prompt says

Enter an input filename: input.txt
File size: 13
Buffer:


  EAX=0000000D  EBX=7EFDE000  ECX=767B18AF  EDX=00405000
  ESI=00000000  EDI=00000000  EBP=0018FF94  ESP=0018FF8C
  EIP=004010BD  EFL=00000202  CF=0  SF=0  ZF=0  OF=0  AF=0  PF=0


  EAX=0000000D  EBX=00405000  ECX=767B18AF  EDX=00405000
  ESI=00000000  EDI=00000000  EBP=0018FF94  ESP=0018FF8C
  EIP=004010C4  EFL=00000202  CF=0  SF=0  ZF=0  OF=0  AF=0  PF=0

Hello World!!

  EAX=00000058  EBX=00405000  ECX=773B36FA  EDX=00405000
  ESI=00000000  EDI=00000000  EBP=0018FF94  ESP=0018FF8C
  EIP=00401104  EFL=00000217  CF=1  SF=0  ZF=0  OF=0  AF=1  PF=1

Bytes written to file [output.txt]: 0
Press any key to continue . . .


I don't know what AF and PF means and if it affects the output, but that is the only thing that gave me a feeling from DumpRegs that could be wrong. Either something wrong with those flags or something wrong with my code in outputting stored buffers

dedndave

i think i found it - lol
the value "stringLength" never gets saved
you intend to use that for something else
you may want to create a new variable called "InputFileLength" to save the length of the input file
then, use that as the number of bytes to write