The MASM Forum Archive 2004 to 2012

Miscellaneous Forums => 16 bit DOS Programming => Topic started by: caprisun on May 06, 2007, 10:14:59 PM

Title: reading a text file
Post by: caprisun on May 06, 2007, 10:14:59 PM

.data
FileName DB "C:\text.txt
Buffer DB ? dup (?)
.code
mov ax,@data
mov ds,ax

mov dx,OFFSET FileName
mov al,2
mov ah,3Dh
int 21h

jc ErrorOpening

mov dx,offset Buffer
mov cx,100
mov ah,3Fh ; function 3Fh - read from file
int 21h


What i don't get is when these commands opens the text file and offsets it to the dx register. Where are all the data stored? and what type of data, such as a string ?
Title: Re: reading a text file
Post by: eek on May 06, 2007, 11:24:18 PM
Use this thing.
A picture is better than a thousand words.

http://www.btinternet.com/~btketman/tutpage.html

DS:DX points to the start so move dx to si (or di)

mov ah,3F ;<read
mov al,00 ;<bl has file handle
mov cx,[BYTES]
;<read 1 page
int 21
mov si,dx   ;  <--------------------------------move dx to si so you can manipulate it
mov cx,ax  ;bytes read


The data gets stored directly after your fixed variables

INTRO  ch10 Hello there
BYTES dw 00FF
OTHER db ?                      ; <-----so from around here you dynamic read starts, dx points to start

To keep going down the text file loop with ah3F int21, ax tells you the number of bytes read to memory.
Title: Re: reading a text file
Post by: japheth on May 07, 2007, 08:18:54 AM

There is also a bug: after successfully have opened a file (AH=3Dh), a handle is returned in AX, which must be moved to BX before doing the read (AH=3Fh).
Title: Re: reading a text file
Post by: MichaelW on May 07, 2007, 04:14:26 PM
Quote from: caprisun on May 06, 2007, 10:14:59 PM
What i don't get is when these commands opens the text file and offsets it to the dx register. Where are all the data stored? and what type of data, such as a string ?
Are you asking where the data for an open file is stored? If so, the answer is that the data is stored in the file, on the disk. When the system opens a file, it essentially reads the directory information for the file and sets up all the data it will need to access the file. MS-DOS stored most of this data in a System File Table (SFT) structure, for an example search  this page (http://www.ctyme.com/intr/rb-2983.htm) for the string:

Format of DOS 4.0-6.0 system file tables

The handle that is returned when you open a file is essentially an index into the SFT. This handle must be passed to the functions that access the file data.

Title: Re: reading a text file
Post by: japheth on May 07, 2007, 07:23:57 PM

> The handle that is returned when you open a file is essentially an index into the SFT.

That's not quite correct. The handle returned is an index into the JFT, which usually is located in the PSP, with an initial size of 20. And the entries in the JFT are (byte) indices into the SFT.

Title: Re: reading a text file
Post by: MichaelW on May 07, 2007, 09:38:23 PM
QuoteThe handle returned is an index into the JFT
Yes, I'm aware of this. I was trying to avoid too much detail, so I used a simplified explanation and qualified it with "essentially". Perhaps it would have been better to use "effectively" instead.
Title: Re: reading a text file
Post by: caprisun on May 08, 2007, 03:51:34 AM
is there another debugger out there that would allow me to input my current code more easily than Ketman?
Title: Re: reading a text file
Post by: eek on May 08, 2007, 09:27:01 AM
I haven't used the debugger yet, I always use the data windows...

Alt-1

then press 'e' to edit and set up a window.

You can look directly into, and observe, any area of memory you like as the program step-executes.

You would probably need

FileRead            cs:si

once you move dx to si after loading a chunk of the file text to memory.
Use Shift and Alt with the up/down/left/right arrows to manipulate the window, and 0-9 to assign the viewable value you want, bytes, words, etc
The value 0 displays text in a readable format.
Title: Re: reading a text file
Post by: caprisun on May 09, 2007, 05:07:19 PM
ok manage to get the output i wanted by just incrementing num.
eg. [si+num]

since I assume that SI is a string I can't use this code to count the sum of array in SI with this?
Quote
L1: add ax, [si]
    add si, 1
    loop L1

my outcome is some large value.

I try using the more generic method


Size = ($ - Buffer)
mov ax, Size


This didn't work, got some illegeal instruction error.

Is there any other method or advise I can try to find the number of element in SI?
Title: Re: reading a text file
Post by: MichaelW on May 09, 2007, 05:54:14 PM
Size is a reserved word. You should have gotten:

error A2008: syntax error : size

Indicating that the problem is with the name "size".


.model small
.stack
.data
  buffer db 10 dup(1),0
  bufsize = $ - buffer
.code
.startup
    mov ax, bufsize         ; ax <- 11
    mov ax, size buffer     ; ax <- 10 (sizeof first initializer)
    mov ax, sizeof buffer   ; as <- 11

    xor si, si              ; zero index
  L1:
    mov al, [buffer+si]     ; get byte at buffer + index
    test al, al             ; test for null
    jz L2                   ; finished
    inc si                  ; increment index
    jmp L1                  ; continue
  L2:
    ; SI = 10
.exit
end

Title: Re: reading a text file
Post by: caprisun on May 09, 2007, 08:30:21 PM
Lol, good thing I didn't use "Size" in my code. I didn't want to cut and paste my code and confused anyone, but it seems that I should cut and paste.

Anyhow, was there specific site you got this code from? this way I won't have to ask to many questions.

Since I don't my own pc infront of me right now, I can't try your code.

By the look of this, I think i would might come into a problem.

Nicole and I were also talking about Altar Boyz. Does any of the following dates work for you?
.data
  buffer db 10 dup(1),0
  bufsize = $ - buffer
.code


In my code, I start buffer as
Nicole and I were also talking about Altar Boyz. Does any of the following dates work for you?
.data
  buffer db ? dup(?)
.code


Reason for this, is because buffer is I store the data of the text file which has to be open with some int10 function.
Since the program first run without knowing the buffer size, will bufsize be able to count the amount of elements?
Title: Re: reading a text file
Post by: MichaelW on May 09, 2007, 11:19:19 PM
The count for the DUP operator must be specified. Using a ? will result in:

error A2009: syntax error in expression

If you need a buffer of some arbitrary size that is unknown at compile time, then depending on the maximum size required, you could allocate the buffer in the initialized (.DATA) or uninitialized (.DATA?) data segments, or allocate it from the OS at run time, after determining the actual required size.
Title: Re: reading a text file
Post by: caprisun on May 10, 2007, 01:21:51 AM
Finally got home and tried to test your original code

First I used Emu8086
gave me first error at
illegal instruction: bufsize = $ - buffer

Second program i tried on FASM

got error on the first line:
.model small

Which complier/assemblier are you using? 
Title: Re: reading a text file
Post by: caprisun on May 10, 2007, 02:09:49 AM
duh.. obviously used masm32
Anyway, when i try complieing your code got 2 errors
error a2006:undefined symbol dgroup
error a2074:cannot access through segment regs....
Title: Re: reading a text file
Post by: eek on May 10, 2007, 02:27:44 AM
hehe  :bg

Thats why I ended up using Ketman.

Nothing flipping worked, even the simplest examples were crippleware.
Trying with java totally did my head in as well...

I must have about twenty different assemblers/compilers on my computer.
Title: Re: reading a text file
Post by: caprisun on May 10, 2007, 02:37:14 AM
what's the point in making this language if it isn't even standard, or at least the compliers  :'(

Title: Re: reading a text file
Post by: eek on May 10, 2007, 02:50:31 AM
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...
Title: Re: reading a text file
Post by: MichaelW on May 10, 2007, 08:08:35 AM
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.
Title: Re: reading a text file
Post by: caprisun on May 10, 2007, 03:18:43 PM
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.


Title: Re: reading a text file
Post by: MichaelW on May 10, 2007, 06:09:43 PM
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.
Title: Re: reading a text file
Post by: caprisun on May 10, 2007, 08:18:28 PM
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
Title: Re: reading a text file
Post by: MichaelW on May 10, 2007, 11:54:08 PM
You must assemble and link in separate steps, as I showed in the batch file I posted.
Title: Re: reading a text file
Post by: caprisun on May 11, 2007, 01:43:16 AM
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?
Title: Re: reading a text file
Post by: MichaelW on May 11, 2007, 02:34:57 AM
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.

Title: Re: reading a text file
Post by: caprisun on May 11, 2007, 09:44:37 PM
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?
Title: Re: reading a text file
Post by: MichaelW on May 11, 2007, 10:56:34 PM
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.
Title: Re: reading a text file
Post by: caprisun on May 12, 2007, 01:22:38 AM
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.

Title: Re: reading a text file
Post by: eek on May 12, 2007, 02:30:22 AM
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.
Title: Re: reading a text file
Post by: MichaelW on May 12, 2007, 05:43:50 AM
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

Title: Re: reading a text file
Post by: eek on May 12, 2007, 08:20:02 AM
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.
Title: Re: reading a text file
Post by: MichaelW on May 12, 2007, 08:38:15 AM
QuoteAssign 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.
A file can be larger than FFFFh bytes, in which case this method will not work. Function 42h returns the length as a 32-bit value, so it will work for files up to 4GB.
Title: Re: reading a text file
Post by: caprisun on May 12, 2007, 02:36:16 PM
Michael, what did for me is similar to what i've done, but instead of int 21, I used int 10.

What I can't get is when I load the data into memory, I can see it there.

How do i access/extract the memory and get each idividual character in their hex decimal form (eg. A = 41h).

In C, there is a simplar function something similar to explode to accomplish this, but in assembly this thing doesn't exist?
Title: Re: reading a text file
Post by: MichaelW on May 12, 2007, 09:24:08 PM
Conversion procedures in assembly do exist. Most of them copy the converted values to a buffer as a null-terminated string. If you have the MASM32 package installed, you can find an example of such a conversion procedure in dw2ah.asm in the m32lib directory, but note that the procedure is 32-bit code and it would need to be modified to work in a 16-bit application. One easy to understand method is to convert each nibble of the value to the equivalent hex character by using the nibble value as an index into a table of hex characters. For example, if your table were defined like this:

hexchars db  "0123456789ABCDEF"

Then:

"A" = 41h = 01000001b
upper nibble = 0100b = 4
the character at offset 4 in the table is "4"
lower nibble = 0001b = 1
the character at offset 1 in the table is "1"
 
"z" = 7Ah = 01111010b
upper nibble = 0111b = 7
the character at offset 7 in the table is "7"
lower nibble = 1010 = 10
the character at offset 10 in the table is "A"

You can extract the lower nibble by ANDing the byte value with 0Fh, and the upper nibble by shifting the byte value right by 4. You can get the indexed character into a register by loading the nibble value into a base or index register and using that register to index the table, for example:

mov dl, hexchars[bx]

Title: Re: reading a text file
Post by: caprisun on May 13, 2007, 05:14:13 AM
so if the value of BX is already know, then that won't be hard to inject the exact character.

I'm just assuming that :
mov dl, hexchar[bx]
that the use of dl register is no significance?


FileNameIn DB "test.txt",0
.
.
.
.code
mov ax,@data      
mov ds,ax

mov dx,OFFSET FileNameIn
mov al,2
mov ah,3Dh
int 21h
.
.
.

mov dx,offset Buffer
mov bx,HandleIn
mov cx,StringLength
mov ah,3Fh
int 21h

.
.
.

mov cx, StringLength      ; length of string
mov si,OFFSET Buffer      ; DS:SI - address of string
xor bh,bh   ; video page - 0
mov ah,0Eh ; function 0Eh - write character

lodsb         ;  AL = next character in string
int 10h ; call BIOS service
loop NextChar


With something like this.. I can't just
mov bx, [si+n]       ; where n>=0
mov dl, hexchar[bx]

to get the lower or upper nibble i need to make that conversion could I?
Trouble is that I have lodsb to mov each SI into AL, but the value that is moved into AL i assume is not the exact hex that I need to do the conversion?
Title: Re: reading a text file
Post by: MichaelW on May 13, 2007, 06:55:22 AM
To access the nibbles you must isolate each of them in a byte.

I used DL in the example because I assumed you were looking for a simpler method than putting the converted characters into a string. By putting the character into DL you can use Interrupt 21h function 2 to display it with just 2 additional instructions. It might help you to know that the DOS display functions call the BIOS Write Teletype function (Interrupt 10h, function 0Eh), so Interrupt 21h function 2 updates the cursor just as the Teletype function does, and it's easier to call.
Title: Re: reading a text file
Post by: caprisun on May 13, 2007, 02:21:32 PM
 :red now we are in the right track.
How do I isolate each byte of this paticular array?

Because whenever I load the Offset buffer, SI always contains the value 66h as the first value, so I can't use SI a my source to extract each individual bytes?
And that is where lodsb, int10 gets it's character to move to AL right before it is display
Title: Re: reading a text file
Post by: MichaelW on May 13, 2007, 08:06:23 PM
This example is coded for the default processor (8086/8088), and because it must access the lower byte it must use BX (hexchars is defined as hexchars db "0123456789ABCDEF"):

    xor bx, bx            ; must zero upper byte
    mov bl, "A"           ; load byte (could be from memory or register)
    push bx               ; preserve it
    mov cl, 4             ; for .86 shift count > 1 must be in CL
    shr bx, cl            ; isolate upper nibble
    mov dl, hexchars[bx]  ; get indexed character from table
    ; Do something with the character
    pop bx                ; recover byte
    and bx,0fh            ; isolate lower nibble
    mov dl, hexchars[bx]  ; get indexed character from table
    ; Do something with the character

This simpler coding requires a .386 or later processor directive (and a .386 or later processor), and it can use any base or index register (practically speaking that means BX, SI or DI).

    movzx si, byte_val    ; must be memory or register
    push si
    shr si, 4
    mov dl, hexchars[si]
    ; Do something with the character
    pop si
    and si, 0fh
    mov dl, hexchars[si]
    ; Do something with the character

And not to confuse the issue, but by using a table were each element contains both of the characters for a byte value, you can avoid having to isolate the nibbles:

.data
    hextable \
    db "000102030405060708090A0B0C0D0E0F"
    db "101112131415161718191A1B1C1D1E1F"
    db "202122232425262728292A2B2C2D2E2F"
    db "303132333435363738393A3B3C3D3E3F"
    db "404142434445464748494A4B4C4D4E4F"
    db "505152535455565758595A5B5C5D5E5F"
    db "606162636465666768696A6B6C6D6E6F"
    db "707172737475767778797A7B7C7D7E7F"
    db "808182838485868788898A8B8C8D8E8F"
    db "909192939495969798999A9B9C9D9E9F"
    db "A0A1A2A3A4A5A6A7A8A9AAABACADAEAF"
    db "B0B1B2B3B4B5B6B7B8B9BABBBCBDBEBF"
    db "C0C1C2C3C4C5C6C7C8C9CACBCCCDCECF"
    db "D0D1D2D3D4D5D6D7D8D9DADBDCDDDEDF"
    db "E0E1E2E3E4E5E6E7E8E9EAEBECEDEEEF"
    db "F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF"
.code

And by combining this table with a .386 or later processor directive and a 32-bit register (that does not need to be a base or index register) you can reduce the code to this (the scaling factor *2 compensates for each table element being 2 bytes in length, and the displacement +1 adjusts the address to the second hex character of the indexed element):

    movzx ebx, byte_val    ; must be memory or register
    mov dl, hextable[ebx*2]
    ; Do something with the character
    mov dl, hextable[ebx*2+1]
    ; Do something with the character


Title: Re: reading a text file
Post by: caprisun on May 13, 2007, 09:54:01 PM
I think I wasn't clear enough and made you end up typing a lot of code that is very useful for me but not for this current sitution.

this is what eek posted a  day ago, and was onto what I has having troubles with
Quote
DS:DX points to the start so move dx to si (or di)

mov ah,3F ;<read
mov al,00 ;<bl has file handle
mov cx,[BYTES]
;<read 1 page
int 21
mov si,dx   ;  <--------------------------------move dx to si so you can manipulate it
mov cx,ax  ;bytes read


what eek posted here answer my question
1) what happens to the data which is read from a .txt file
Ans: it is store in SI

Next situtation/question/problem..

2) In SI the value (Hexdecimal number) doesn't correspond to the hex value of the data loaded from text
example, the text file contains letter "A" = 41h
but, the SI doesn't contain 41h, instead it is some arbitrary number.

So the question that still remains, where do I get my hex value of 'A' which was read from the .txt file?



So basicly, the information you gave me is what I would implement after I get my solution for Question 2?
Title: Re: reading a text file
Post by: MichaelW on May 13, 2007, 11:40:46 PM
Trying code is no problem. The difficult part is trying to guess what you are asking, what you are trying to do, and what you know and don't know.
Quote
what happens to the data which is read from a .txt file
Ans: it is store in SI
No, the data is not stored in SI or in any other register. The data read from the file is stored in an application-defined buffer. You pass the address of this buffer in DX when you call the function that reads the file. If you do not have a reference for this type of information, you should get Ralf Brown's Interrupt list. An HTML version is here:

http://www.ctyme.com/rbrown.htm

And the download version here:

http://www-2.cs.cmu.edu/~ralf/files.html

I posted code that reads the contents of a small file into a buffer, and then used DEBUG to dump the contents of the buffer, here:

http://www.masm32.com/board/index.php?topic=7245.msg53846#msg53846

To display the contents of the buffer in hex you would need to read the contents of the buffer a byte at a time, convert the byte value to hex, and display the hex.
Title: Re: reading a text file
Post by: eek on May 14, 2007, 02:30:47 AM
"Ans: it is store in SI"

I've been drinking tonite but:
NO.
si only points at it. I MADE si point at it.

You can point di at it if you want, or make your own window in ketman.


The buffer is at the bottom of the code

Thats the problem with this ASM stuff.
It takes a while before you get the bigger picture.

In a bout 12 months I'll be asking you wtf is going on...
Title: Re: reading a text file
Post by: eek on May 14, 2007, 02:37:09 AM
Quote2) In SI the value (Hexdecimal number) doesn't correspond to the hex value of the data loaded from text
example, the text file contains letter "A" = 41h
but, the SI doesn't contain 41h, instead it is some arbitrary number.

So the question that still remains, where do I get my hex value of 'A' which was read from the .txt file?

have you tried

mov si,C1    ;yet ??

Its all there, thats the thing, we don't need to explain it, the machine is laid out for you.

You can see the file text in the data strip, and experiment with it.

Title: Re: reading a text file
Post by: caprisun on May 14, 2007, 04:05:29 PM
Quote from: eek on May 14, 2007, 02:37:09 AM
QuoteI've been drinking tonite but:
Lol, i need a drink too.

Anyhow, thank you, Michael and eek for all your help. I know it's fustrating teaching a noobie new tricks in a short amount of time
but you guys maintain your cool.  :U


The problem is not assembly, it's my professor.
He wants us to program with the knowledge in his "head" and not from whatever we gain from our text book.
Must consentrate on my other subjects, so this is going to be the end, for now.

ATM, I wish I was "Sylar" (from Heroes).  :bdg
Title: Re: reading a text file
Post by: skywalker on May 14, 2007, 05:01:13 PM
Some things that'll help you.

grdb debugger debugger forr 16 and 32 bit apps (command line)

Take frequent breaks.

Get Ralph Brown's Interrupt List

Search, download and study any code you can find

Take frequent breaks.

Get IDA for windows (dissassembles and can make an asm source code file as well)