The MASM Forum Archive 2004 to 2012

General Forums => The Campus => Topic started by: krikara on November 02, 2010, 02:53:24 AM

Title: Read and Writing files
Post by: krikara on November 02, 2010, 02:53:24 AM
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.
Title: Re: Read and Writing files
Post by: 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
Title: Re: Read and Writing files
Post by: krikara on November 02, 2010, 03:11:55 AM
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.
Title: Re: Read and Writing files
Post by: dedndave on November 02, 2010, 03:39:38 AM
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
Title: Re: Read and Writing files
Post by: krikara on November 02, 2010, 03:53:50 PM
Okay so far I combined the two programs, but I have still yet to make the input turn into the out put.
Title: Re: Read and Writing files
Post by: dedndave on November 02, 2010, 04:17:21 PM
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
Title: Re: Read and Writing files
Post by: krikara on November 02, 2010, 04:29:43 PM
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
Title: Re: Read and Writing files
Post by: dedndave on November 02, 2010, 04:41:54 PM
well - we usually post entire programs zipped
small snippets get posted literally

give me a while to look it over   :bg
Title: Re: Read and Writing files
Post by: dedndave on November 02, 2010, 04:52:04 PM
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
Title: Re: Read and Writing files
Post by: dedndave on November 02, 2010, 04:58:24 PM
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 ?
Title: Re: Read and Writing files
Post by: krikara on November 02, 2010, 05:15:31 PM
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 :/
Title: Re: Read and Writing files
Post by: dedndave on November 02, 2010, 05:25:35 PM
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
Title: Re: Read and Writing files
Post by: krikara on November 02, 2010, 05:28:31 PM
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.
Title: Re: Read and Writing files
Post by: krikara on November 02, 2010, 05:30:23 PM
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
Title: Re: Read and Writing files
Post by: dedndave on November 02, 2010, 05:36:22 PM
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
Title: Re: Read and Writing files
Post by: FORTRANS on November 02, 2010, 05:53:16 PM
Quote from: krikara on November 02, 2010, 05:30:23 PM
I don't know what AF and PF means and if it affects the output,

Hi,

   AF is the Auxiliary carry Flag.  Used with BCD arithmetic.
PF is the Parity Flag.  It shows whether the accumulator has
an even or odd number of bits set by an operation.  Neither
has an effect here.

HTH,

Steve N.
Title: Re: Read and Writing files
Post by: krikara on November 02, 2010, 06:27:52 PM
Quote from: dedndave on November 02, 2010, 05:36:22 PM
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

NICE!!!
You found the error. All I had to do was    mov stringLength, eax    after the program read the input file !! :D

Thanks a bunch.
Title: Re: Read and Writing files
Post by: brethren on November 02, 2010, 07:36:20 PM
QuoteI 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 are the general steps

call OpenInputFile parameter is a filename ("input.txt") ps this file must already exist
save the return value, eax, which is a filehandle
call ReadFromFile, parameters are the saved filehandle, a pointer to a buffer and number of bytes to read
call CloseFile with the filehandle

manipulate the buffer in whatever way you see fit

call CreateOutputFile parameter is a filename ("output.txt")
save the return value, eax, which is a filehandle
call WriteToFile, parameters are a filehandle, a pointer to the buffer you manipulated and the number of bytes to write
call CloseFile with the filehandle
Title: Re: Read and Writing files
Post by: dedndave on November 02, 2010, 11:20:56 PM
seems like it should have created a 0-length file before the fix   :P
Title: Re: Read and Writing files
Post by: RuiLoureiro on November 04, 2010, 04:28:36 PM
Quote from: krikara on November 02, 2010, 02:53:24 AM
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.
                Try to use APIs and masm. It is easy. Why not ?
RuiLoureiro
Title: Re: Read and Writing files
Post by: dedndave on November 04, 2010, 06:50:21 PM
i am with you, Rui
i wouldn't use HLA - lol
but, it's for a school project i think
they are probably supposed to use Kip's library
Title: Re: Read and Writing files
Post by: RuiLoureiro on November 04, 2010, 08:06:58 PM
Quote from: dedndave on November 04, 2010, 06:50:21 PM
i am with you, Rui
they are probably supposed to use Kip's library

dedndave,
           Ok, so we need to know Irvine32 stuff, no ?  :wink
           We waste time with ...

brethren,
           It seems it doesnt work when inputbuffer is 50 and outputbuffer is 500
           
           So we need to read the input several times to fill in the outputbuffer
           and then alter the outputbuffer and at last we save the outputbuffer.

           If inputbuffer = outputbuffer = 500 or so, ok it seems to work
           We dont know all the problem ...
           We may use the outputbuffer as the inputbuffer ?
           What is the input file length ?
Title: Re: Read and Writing files
Post by: dedndave on November 04, 2010, 11:52:25 PM
well - i am familiar with Kip's older stuff - so that was painless
but - they would be better off to learn the API's
that is the real meat of writing windows code, in any language

btw, guys, that problem was fixed several posts ago - lol
http://www.masm32.com/board/index.php?topic=15210.msg123546#msg123546
Title: Re: Read and Writing files
Post by: RuiLoureiro on November 05, 2010, 03:52:37 PM
dedndave,
            Try this Files2.zip (=.exe + .asm+ .inc+...).
            Whats wrong ?
Title: Re: Read and Writing files
Post by: dedndave on November 05, 2010, 04:10:07 PM
i like it   :U
but, it may be a bit complicated for the beginner   :P
(we are in the Campus sub-forum - lol)
Title: Re: Read and Writing files
Post by: RuiLoureiro on November 05, 2010, 07:01:39 PM
Quote from: dedndave on November 05, 2010, 04:10:07 PM
i like it
but, it may be a bit complicated for the beginner 

dedndave,
            Ok thank you   :green2
            It is simple ( and have some problems )
            It is based on 2 procedures: ReadText and WriteText
           
            Whenever it saves a text it saves 12000 bytes ( _lTextBuffer=12000 )
            whenever it reads, it try to read _lTextBuffer bytes only
            this was only to show the problem