News:

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

huge problem with reading files...

Started by Wojtek.wk, November 28, 2009, 04:48:50 PM

Previous topic - Next topic

Wojtek.wk

Hello! First of all, sorry if my English isn't OK. I'm writing to ask you for help. I'm working on my project many days and many hours and unfortunately, it doesn't work. Here's what I have to do: I have to read names of input files (there can be many of them) from command line, then read name of output file to create and the sign which will be a separator. And then I have to make one file (output) from all of input files. Maybe it would be easier if I gave some example:
InputFile1:
abc
def
InputFile2:
123
456
789
Separator let be the colon. And the output should look like that:
OutputFile:
abc:123
def:456
:789

What I've done and I'm sure it works is reading from the command line. But then I try to read all of these input files and write them into output file, but with no result. My program works only if there is one input file given. Could you please look at the part of this code, where a problem definetely is?:
main:
      mov   ax,es
      mov   ds,ax
      mov   word ptr ds:[aktplik],1            ;aktplik - the file I am reading from at the moment

      mov   word ptr ds:[index],0            ;start from the beginning of array

      do_pliku:

         czytaj:
            mov   ax,word ptr ds:[index]      ;index tymczasowo pod ax
            cmp   word ptr ds:[array+ax],0   ;file already closed? (number below 0 means: "yes")
            jb   next
            czytajznak:
               mov   ax,word ptr ds:[index]
               mov   bx,word ptr ds:[array+ax]   ;handle
               mov   cx,1
               mov   dx,offset bufor
               mov   ah,3Fh
               int   21h
               jc   error_read
               
               cmp   ax,0            ;if eof (nothing read)...
               je   eof            

               cmp   byte ptr ds:[bufor],10d      ;if ENTER...
               je   next
               cmp   byte ptr ds:[bufor],13d      ;if carriage return...
               je   czytajznak

            zapisz:
               mov   ah,40h
               mov   bx,word ptr ds:[outuchwyt]   ;handle
               mov   cx,1
               mov   dx,offset bufor
               int   21h
               jc   error_write
               jmp   czytajznak

         next:

            mov   cx,word ptr ds:[aktplik]
            cmp   cx,word ptr ds:[iloscwej]      ;all files in that iteration?
            jne   niewszystkie
            
            wszystkie:
               mov   ax,word ptr ds:[ilosczamk]
               cmp   ax,word ptr ds:[iloscwej]
               je   close_output         ;of all of files are closed, exit

               mov   ah,40h            ;put the next line (enter) in the output
               mov   bx,word ptr ds:[outuchwyt]
               mov   cx,1
               mov   byte ptr ds:[bufor],10d      ;ENTER
               mov   dx,offset bufor
               int   21h
               jc   error_write

               mov   ah,40h
               mov   bx,word ptr ds:[outuchwyt]
               mov   cx,1
               mov   byte ptr ds:[bufor],13d      ;carriage return
               mov   dx,offset bufor
               int   21h
               jc   error_write

               mov   word ptr ds:[aktplik],1      ;iterate once again from the first file
               mov   word ptr ds:[index],0      ;index=0 (begin from the first file once again)
               jmp   czytaj

            niewszystkie:
               mov   ah,40h            ;write separator
               mov   bx,word ptr ds:[outuchwyt]
               mov   cx,1
               mov   dx,offset separator
               int   21h
               jc   error_write

               add   word ptr ds:[aktplik],1      ;next file
               add   word ptr ds:[index],2
               jmp   czytaj

         eof:                  ;end of file
            add   word ptr ds:[ilosczamk],1   ;increment the number of closed files
            mov   ax,word ptr ds:[index]
            mov   bx,word ptr ds:[array+ax]   ;handle
            mov   ah,3eh
            int   21h
            jc   error_close   
            mov   ax,word ptr ds:[index]
            mov   word ptr ds:[array+ax],-1   ;delete handle
            jmp   next            ;next file


And there are variables:

      array      dw    20 dup(?)   ;array of handles
      separator    db    ' '      ;separator (space default)
      outuchwyt   dw   0      ;handle to output file
      iloscwej   dw   0      ;quantity of input files
      ilosczamk   dw   0      ;quantity of closed files
      index      dw   0      ;used with array - to iterate
      bufor      db   0      ;buffor to read from files
      aktplik   dw   0      ;file I am reading from at the moment

Sorry for not changing the names of the variables into English, but I am sure I would forget about one and this could cause some problems in understanding the code.
Thank you in advance for help!!

dedndave

hi Wojtek and welcome to masm32 forum   :U
first, Polish is ok - we wouldn't understand any better if the labels were in English - lol
second, this is a 16-bit program, and we have a special forum for that (near the bottom of the list)
the thread will probably get moved there

as for the filenames, i don't think "@" or ":" are allowed in filenames, if that is what you are trying to do
give me a little time to read the code over and see what is going on
Dave

dedndave

ok - a few things
first, i don't see the "Create File" or "Open File" calls
give us the complete listing
if it is long, you may ZIP the file and attach it to your post
underneath the Reply window, there is a hyper link for "Additional Options..." click that and attach a ZIP file
second, if you are going to read and write files 1 byte at a time, not only will it be slow, it will grind on the hard drive
i suggest you set up a 32 Kb buffer and use it to read and write files in 32 Kb pieces

Wojtek.wk

Hello! Thank you for your fast reply. I didn't realised, that this is 16-bit program.
The problem is not in filenames - all files are properly opened.
I give you time, of course :) Thank you for your help in advance.
PS: maybe it would be helpful if I provide you the code where I read the command line - maybe there is something wrong?
Here it is:

        mov   ah,62h
   int   21h
   mov   ds,bx

   xor   cx,cx
   mov   cl,byte ptr ds:[80h]
   mov   bx,81h

   czytanie:
      cmp   cx,0         ;is there something?
      je   main

      dec   cx         ;decresing number of signs in the line
      inc   bx         ;going right
      cmp   byte ptr ds:[bx],' '   ;is it space?
      je   czytanie

      cmp   byte ptr ds:[bx],'-'   ;is it '-'?
      jne   exit                           ;if not space and not '-' : exit

      
      parametry:         ;parameters
         dec   cx
         inc   bx

         parametr_i:
            cmp   byte ptr ds:[bx],'i'   ;input
            je   plik_wej

         parametr_o:
            cmp   byte ptr ds:[bx],'o'   ;output
            je   plik_wyj

         parametr_t:
            cmp   byte ptr ds:[bx],'t'   ;separator
            je   sep


   
      plik_wej:         ;input file
         
         cmp   cx,0   
         je   pomoc
         dec   cx         ;looking for the beginning of the name of the file
         inc   bx
         cmp   byte ptr ds:[bx],' '
         je   plik_wej

         mov   word ptr es:[namestart],bx   ;saving the name's beginning

         next_in:
            cmp   cx,0         ;if there are input files given only
            je   wklej0wej         
            dec   cx         ;looking for the end of file
            inc   bx
            cmp   byte ptr ds:[bx],' '
            jne   next_in
   
            wklej0wej:
               mov   byte ptr ds:[bx],0   ;putting 0 at the end

            mov   ah,3dh            
            mov   dx,word ptr es:[namestart]   
            xor   al,al            
            int   21h
            jc   error_open         
            push   bx            
            mov   bx,word ptr es:[index]      
            mov   word ptr es:[array+bx],ax   ;saving handle in the array
            pop   bx            
            add   word ptr es:[index],2      ;next element in the array
            add   word ptr es:[iloscwej],1   ;quantity of input files +1

            jmp   czytanie      ;return to reading of the command line
   


      plik_wyj:         ;output file

         cmp   cx,0         
         je   pomoc
         dec   cx      
         inc   bx         
         cmp   byte ptr ds:[bx],' '   
         je   plik_wyj

         mov   word ptr es:[namestart],bx

         next_out:
            cmp   cx,0                  
            je   wklej0wyj
            dec   cx         
            inc   bx         
            cmp   byte ptr ds:[bx],' '
            jne   next_out
            
            wklej0wyj:
               mov   byte ptr ds:[bx],0   
   
            mov   ah,3ch            
            mov   dx,word ptr es:[namestart]   
            xor   cx,cx         
            int   21h
            jc   error_cr         
            mov   word ptr es:[outuchwyt],ax

            jmp   czytanie   


      sep:            ;separator

         cmp   cx,0      
         je   pomoc

         dec   cx      
         inc   bx         
         cmp   byte ptr ds:[bx],' '   
         je   sep                  

         push   cx            
         mov   cl,byte ptr ds:[bx]      
         mov   byte ptr es:[separator],cl   
         pop   cx            
         dec   cx
         inc   bx
         jmp   czytanie      

If the user haven't given the name of the output file, joined input files should be written on the standard output (screen)

THX

dedndave

no no - lol
give us the complete program so we can make sense of it
i don't want to sort it all out in pieces - lol
best to attach it as a ZIP

japheth



               mov   ax,word ptr ds:[index]
               mov   bx,word ptr ds:[array+ax]   ;handle


This code isn't valid because register AX cannot be used as index register.

Wojtek.wk

I'm almost sure that ax can be used as index register - I've tried many times and it worked...
I send you my program in attachment (sorry for polish comments but there are so many of them that it's hard do delete all of them)

Wojtek.wk

I have to apologize japheth - I changed all the places with ax - instead I put BP. AND IT WORKS!!! THANK YOU SO MUCH!!!

japheth


> I'm almost sure that ax can be used as index register

It's the assembler's job to reject invalid code, but apparently there's a bug in Masm. It's unable to detect the error (tested with v6.15, v8 and v9).

MichaelW

I tested ML 6.11, 6.14, 6.15, 7.00, and 7.11, and they all failed to detect the errors, but they will detect the errors with the equivalent syntax array[ax].
eschew obfuscation

jj2007

For those who can't believe it, here a testbed ;-)

Quote.Model small   ; credits to DednDave
.Stack 512

.Data
choice   dw MsgText, Msg2
MsgText   db "Hello World", 13, 10, "$"
Msg2   db "This is the second message", 13, 10, "$"

.Code

_main proc FAR

; set the DS register to DGROUP (will fail with later Masm versions - use ml 6.14, 6.15 or JWasm)
   mov ax, @DATA
   mov ds, ax

; display the message: put 0 for the first, 2 for the second message
   mov ax, 2
   mov dx,word ptr ds:[choice+ax]   ;
works with bx but fails with ax
   mov ah, 9
   int 21h

; wait for a key
   mov ah, 0
   int 16h

; the DOS equivalent to ExitProcess
   mov ax, 4C00h
   int 21h

_main endp

end _main

dedndave