News:

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

reading a text file

Started by caprisun, May 06, 2007, 10:14:59 PM

Previous topic - Next topic

caprisun

what's the point in making this language if it isn't even standard, or at least the compliers  :'(


eek

It takes about 12 months before you become moderately conversant with a compiler if you've never done this stuff at all before.

That first 12 months is the toughest bit, because you make huge amounts of effort and yet you often get no return at all.

Then slowly you start to "get-it" and produce working snippets, then you look at slightly bigger projects, putting your snippets together.

Anger management can be an issue after a bad night  :lol


What kept me going when it got really bad was the belief that I would eventually get more out it than I was putting in.

This turned out to be true, but it was a slog, and I'm really still just a noobie coder.

The next stage is organising your work properly, when you do a slightly bigger project you can end up in a bit of a mess.... :eek

That's the stage I'm at now....you end up going round in circles as the decision making routines pile up...

MichaelW

The code I posted assembles, links, and runs without error. I used the ML.EXE from the MASM32 package, the 16-bit linker available from the forum web site, and this batch file to assemble and link:

ML /c cap.asm
pause
LINK16 cap.obj;
pause

You cannot use the 32-bit linker included in the MASM32 package for 16-bit applications, and even if you replaced the 32-bit linker with a 16-bit linker, you still could not use the batch files included in the MASM32 package to assemble and link a 16-bit application. To avoid problems I put all of my 16-bit stuff in a separate directory. This directory contains my source files, along with copies of ML.EXE and ML.ERR from the MASM32\bin directory, the 16-bit linker renamed to LINK16.EXE, and the batch files I use to assemble and link. To test programs that do not generate any output, like the example, or programs that have some serious problem, or that I suspect may have a serious problem, I normally load the program into DEBUG, the 16-bit debugger that is included with Windows. If you do a search of the forum you should be able to find a DEBUG tutorial.
eschew obfuscation

caprisun

Ok, I think I'm gonna shoot myself. :'(

1)
I copy, ml.exe, ml.err and link563 (rename to link16), and place them inside the same dir where my asm file is at
in cmd, typed "ml /c test.asm link16 test.obj"
-assembling test.asm
a1000 cannot find link16

2)
trying to debug using windows debug
typed
"c:\path\file.asm" (also, tried adding [], as instructed in MichaelW's Debug tutorial)

wouldn't load.
get ^error.



MichaelW

Lnk563.exe is a self-extracting archive that contains the 16-bit linker and several other files. The 16-bit linker is named link.exe, but I change the name to link16.exe to avoid confusing it with the 32-bit linker also named link.exe. Take care not to extract Lnk563.exe in the MASM32 bin directory or the 16-bit linker will overwrite the 32-bit linker.

I usually run DEBUG as the last command in the batch file that I use to assemble and link. For the batch file I posted the command line would be:

DEBUG cap.exe

Note that you must specify the extension.
eschew obfuscation

caprisun

no wonder so many files got extracted from that link365..

Still I can't assmeble the file.
Since "LINK" was extracted, I should have a problem assembling by typing
"ml /c test.asm LINK a.obj"
but, i get Link cannot be found

Tryed
"ml /c test.asm LINK.exe a.obj"

got bunch of lines of "invalid lines in file"
last line "error count exceeds 100"

did I forget to do something?

BTW, did just ml /c test.asm and it assembly a test.obj just fine

MichaelW

You must assemble and link in separate steps, as I showed in the batch file I posted.
eschew obfuscation

caprisun

Ok, i think i also manage to get it to debug because when i typed in -u
I get all the segments and such.

but how do i debug so that I could see the register, data segments change line by line?
or it's not possible with windows debug, and that is something I would find in only Ketman?

MichaelW

The DEBUG that comes with Windows is just a somewhat later version of the DEBUG that came with the first versions of DOS. You can step through the code using the Trace and Proceed commands. The tutorial covers this, and more.

eschew obfuscation

caprisun

Ok, got everything to work, and now to the hard part.

If I load a file with 100 characters inside it.
I must assign cx a value of bytes to read.
1) assign to big programs reads the 100 characters plus other gibberish.
2) assign to small, the charcters get cut off.

I can't a function/handle that would load the size of the file.

On the other hand, if I were to open the file and read it (assigning a larger cx value), and find out what the end of line is?
If this is possible, what carry and in where would I see it?

MichaelW

Interrupt 21h function 3Fh will read up to the number of bytes specified in CX, and assuming no error occurs it will return the number of bytes actually read. It will not read more than the number of bytes specified in CX (otherwise a buffer overflow could occur), but it may read less when it reaches the end of the file. There are multiple methods of getting the length of the file, but I think Microsoft intends that you use Interrupt 21h function 42h, Move File Pointer. Basically, you specify the move method as 2 (start move at the end of the file) and the offset as zero, so the function moves the file pointer to the end of the file, and returns the new pointer position.
eschew obfuscation

caprisun

Thanks for your input.

I just need one more suggestion/help because if I can't get a solution to this then i'll won't be able to move on

To show clearly what i can't solve is this:

This is from a book, I give it the benfit of the doubt that it is 100% correct


.data

arrayW  WORD  100h,200h,300h
.code
mov ax,arrayW           ; AX = 100h
mov ax,[arrayW+2] ; AX = 200h


That is excually what I want to achieve.
This is my code :


.data
FileNameIn DB "test.txt",0
.code

mov ax,@data       ; base address of data segment
mov ds,ax          ; put this in ds
mov dx,OFFSET FileNameIn ; put address of filename in dx
mov al,2            ; access mode - read and write
mov ah,3Dh        ; function 3Dh -open a file
int 21h


mov dx,offset Buffer ; address of buffer in dx
mov bx,HandleIn ; handle in bx
mov cx,MaxSize ; amount of bytes to be read
mov ah,3Fh          ; function 3Fh - read from file

mov ax, [si]
mov ax, [si+1]
mov ax, [si+2]
mov ax, [si+3]
mov si, OFFSET Buffer
mov ax, [si]
mov ax, [si+1]
mov ax, [si+2]
mov ax, [si+3]



Most of the relevent code, and I did all the ax mov just to see what's happening.. and what I see is not the values  contain inside "test.txt"
Instead, I assume that the array have move the offset/address (whatever that is) into ax as I increment SI.

This what I can't figure out is how to get the values in test.txt (eg. A B C) and mov them from the array into AX in hex, so that I can manupulate it?

I try following each AX register and record the values to see if there is some althorim I can figure that would translate into those individual characters, but the values keep going up and down as i increment.. so I'm totally suck.


eek

You can read a file called test.txt in ketman with this.
(I havent put a closefile routine on it, so you can't edit+save the textfile in windows while ketman has control of it)

ZONE                        S L
org cs:100
WB1 ;READ A FILE

mov cx,F         ;ZRS read F bytes
mov ah,3D       ;<open file F1
mov al,02         ;<read/write
mov dx,F1        ;filename
mov si,dx         ;peek
int 21

mov bl,al          ;file handle
mov ax,3F00    ;Read:cx has F bytes
mov dx,C1       ;buffer
int 21              ;
mov si,C1        ;peek at start of read string in memory

F1 ch10 test.txt$  ;The $ sign should be a Ctrl-0. (zero/Null terminated) but it wont display in here
B1 db X X X          ;just a block of Xs to make a space, (easier to view)
C1 db ?                ;variable Buffer, will receive the F bytes read, (you can change F to FF etc)

END
_______________  ;null blocks, a string of Ctrl-0s


You can assemble this and step through it.

MichaelW

caprisun,

Your code lacks the int 21h instruction for the read from file function.

This is your code with a few small changes, and with the other necessary components added:

.model small
.stack
.data
    Buffer      DB 64h dup("X")
    FileNameIn  DB "test.txt",0
.code
.startup
    nop
    mov dx,OFFSET FileNameIn  ; put address of filename in dx
    mov al,2                  ; access mode - read and write
    mov ah,3Dh                ; function 3Dh -open a file
    int 21h
    nop
    mov dx,offset Buffer      ; address of buffer in dx
    mov bx, ax                ; handle in bx
    mov cx,64h                ; amount of bytes to be read
    mov ah,3Fh                ; function 3Fh - read from file
    int 21h
    nop
.exit
end

I added the nop's just to make the unassembled code easier to follow. I assembled and linked this to cap2.exe, and created a file named test.txt that contained the four bytes "ABCD". This is the DEBUG output from my analysis of the code, with comments added:

-n cap2.exe                               ; specify Name of file to load

-l                                        ; Load it

-u                                        ; Unassemble first ~ 32 bytes

0B69:0000 BA6C0B        MOV DX,0B6C
0B69:0003 8EDA          MOV DS,DX
0B69:0005 8CD3          MOV BX,SS
0B69:0007 2BDA          SUB BX,DX
0B69:0009 D1E3          SHL BX,1
0B69:000B D1E3          SHL BX,1
0B69:000D D1E3          SHL BX,1
0B69:000F D1E3          SHL BX,1
0B69:0011 FA            CLI
0B69:0012 8ED2          MOV SS,DX
0B69:0014 03E3          ADD SP,BX
0B69:0016 FB            STI
0B69:0017 90            NOP
0B69:0018 BA6800        MOV DX,0068
0B69:001B B002          MOV AL,02
0B69:001D B43D          MOV AH,3D
0B69:001F CD21          INT 21
-u                                        ; Unassemble next ~32 bytes

0B69:0021 90            NOP
0B69:0022 BA0400        MOV DX,0004       ; note offset of buffer
0B69:0025 8BD8          MOV BX,AX
0B69:0027 B96400        MOV CX,0064
0B69:002A B43F          MOV AH,3F
0B69:002C CD21          INT 21
0B69:002E 90            NOP               ; use this address for a breakpoint
0B69:002F B44C          MOV AH,4C
0B69:0031 CD21          INT 21            ; end of code
0B69:0033 005858        ADD [BX+SI+58],BL ; this is just garbage
0B69:0036 58            POP AX            ; that happened to be
0B69:0037 58            POP AX            ; in memory
0B69:0038 58            POP AX
0B69:0039 58            POP AX
0B69:003A 58            POP AX
0B69:003B 58            POP AX
0B69:003C 58            POP AX
0B69:003D 58            POP AX
0B69:003E 58            POP AX
0B69:003F 58            POP AX
0B69:0040 58            POP AX
-g 2e                                     ; Go (execute) to breakpoint

; After a breakpoint, trace, or proceed command DEBUG displays the registers
; and flags, and the next intruction. Note the NC = no carry, indicating that
; the function succeeded, which also indicates that the first function
; succeeded.

AX=0004  BX=0005  CX=0064  DX=0004  SP=0480  BP=0000  SI=0000  DI=0000
DS=0B6C  ES=0B59  SS=0B6C  CS=0B69  IP=002E   NV UP EI PL NZ NA PO NC
0B69:002E 90            NOP
-d 4 L 64                     ; Dump 64h bytes of data starting at offset 4

0B6C:0000              41 42 43 44-58 58 58 58 58 58 58 58       ABCDXXXXXXXX
0B6C:0010  58 58 58 58 58 58 58 58-58 58 58 58 58 58 58 58   XXXXXXXXXXXXXXXX
0B6C:0020  58 58 58 58 58 58 58 58-58 58 58 58 58 58 58 58   XXXXXXXXXXXXXXXX
0B6C:0030  58 58 58 58 58 58 58 58-58 58 58 58 58 58 58 58   XXXXXXXXXXXXXXXX
0B6C:0040  58 58 58 58 58 58 58 58-58 58 58 58 58 58 58 58   XXXXXXXXXXXXXXXX
0B6C:0050  58 58 58 58 58 58 58 58-58 58 58 58 58 58 58 58   XXXXXXXXXXXXXXXX
0B6C:0060  58 58 58 58 58 58 58 58                           XXXXXXXX
-g                                        ; continue execution


Program terminated normally
-q                                        ; quit debug

eschew obfuscation

eek

Quote from: caprisun on May 11, 2007, 09:44:37 PM
I can't a function/handle that would load the size of the file.

On the other hand, if I were to open the file and read it (assigning a larger cx value), and find out what the end of line is?
If this is possible, what carry and in where would I see it?


Assign FFFF to cx, and Int21 3F will put the actual number of bytes read into ax, a number which you can then manipulate/use in your routine.