1

I recently watched a tutorial on how to read string in assembly language masm 8086.
I want to write this into my file called 'TEST.txt'.
Below is the text

Ali|RM1000
Abu|RM1500

but I only can print out this

Ali|RM1000
Abu|RM1500
Abu|RM1500

The name 'Abu' and 'RM1500' got printed out twice in the txt file. I also wanted to ask whether I can read the string in assembly just like in java, using split("\|"). I would appreciate anyone helping me with this.

.MODEL SMALL
.STACK 100H
.DATA
FNAME DB 'TEST.TXT',0
HANDLE DW ?
MSG DB 'Ali|RM1000', 13, 10
MSG2 DB 'Abu|RM1500', 13, 10
BUFFER DB 25 DUP(?)
COUNT DB 10
.CODE 
MAIN PROC
MOV AX,@DATA
MOV DS,AX

;***************OPENING A NEW FILE***************;

; MOV AH,3CH
; MOV DX,OFFSET(FNAME)
; MOV CL,1
; INT 21H
; MOV HANDLE,AX


;***************CLOSEING A FILE***************;
; MOV AH,3EH
; MOV DX,HANDLE
; INT 21H

;***************OPENING AN EXISTING FILE***************;

MOV AH,3DH
MOV DX,OFFSET(FNAME)
MOV AL,1  ; 1 MEAN FOR WRITING PURPOSE 
INT 21H
MOV HANDLE,AX

MOV AH,40H
MOV BX,HANDLE
MOV CX,25
MOV DX, OFFSET(MSG)
INT 21H

MOV AH,40H
MOV BX,HANDLE
MOV CX,25
MOV DX, OFFSET(MSG2)
INT 21H

MOV AH,3EH
MOV DX,HANDLE
INT 21H

;***************OPENING READING FILE***************;
MOV AH,3DH
MOV DX,OFFSET(FNAME)
MOV AL,0  ; 1 MEAN FOR WRITING PURPOSE 
INT 21H
MOV HANDLE,AX

MOV AH,3FH
MOV BX,HANDLE
MOV DX,OFFSET(BUFFER)
MOV CX,10
INT 21H

;***************DISPLAYING 10 BYTES***************;
MOV SI,OFFSET(BUFFER)
L1:
MOV AH,2
MOV DL,[SI]
INT 21H
INC SI
DEC COUNT
JNZ L1

MOV AH,4CH
INT 21H
MAIN ENDP
END MAIN
Michael Petch
  • 46,082
  • 8
  • 107
  • 198
LIM WENG NI
  • 33
  • 1
  • 4
  • 2
    I don't think MS-DOS has a string `split()` function that takes a regex. You could of course write one, if you pick a way for it to return an array of strings, but it would be much simpler to write something along the lines of the C standard library's `strtok` which you'd call in a loop. (https://en.cppreference.com/w/c/string/byte/strtok / [How does strtok() split the string into tokens in C?](https://stackoverflow.com/q/3889992) ) - C was designed to be only one level up from assembly in terms of how it compiles and what built-in features it has. Like asm, lists require loops. – Peter Cordes Sep 18 '22 at 05:25
  • 2
    You are writing too much in the first write call. There's not `split` service but you can easily implement one. In assembly the exact expected usage of a function matters for its design, `split` is almost always an overkill, `strtok` is usually enough. In your case you may not even need to actually split the string, it all depends on how you expect the function to be **used**. Which we don't know. – Margaret Bloom Sep 18 '22 at 08:59

1 Answers1

1
MSG DB 'Ali|RM1000', 13, 10
MSG2 DB 'Abu|RM1500', 13, 10
BUFFER DB 25 DUP(?)

You are opening an existing file for output and then you write 25 bytes to it, twice. Your file's first 50 bytes will be:

'Ali|RM1000', 13, 10, 'Abu|RM1500', 13, 10, 0
'Abu|RM1500', 13, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
MOV AH, 3Eh
MOV DX, HANDLE
INT 21h

The handle must go in the BX register!

Apply these corrections:

MOV DX, OFFSET(FNAME)
MOV AX, 3D01h         ; DOS.OpenFile
INT 21h               ; -> AX CF
JC  AnErrorOccured    ; What if ?
MOV HANDLE, AX        ; Probably a redundant store !

MOV DX, OFFSET(MSG)
MOV CX, 10 + 2        ; Length of the text including 13, 10
MOV BX, AX            ; HANDLE
MOV AH, 40h           ; DOS.WriteFile
INT 21h               ; -> AX CF
JC  AnErrorOccured    ; What if ?
CMP AX, CX
JNE AnErrorOccured    ; What if ?

MOV DX, OFFSET(MSG2)  ; No need to repeat setting CX and BX
MOV AH, 40h           ; DOS.WriteFile
INT 21h               ; -> AX CF
JC  AnErrorOccured    ; What if ?
CMP AX, CX
JNE AnErrorOccured    ; What if ?

MOV AH, 3Eh           ; DOS.CloseFile
INT 21h               ; -> AX CF
                      ; Don't care about CF
Sep Roland
  • 33,889
  • 7
  • 43
  • 76
  • oh thanks for the corrections, I would like to ask, if I wanted to add Alvin|RM1200 to the text files, but the length stored at cx is only 12 including the 13, 10, and the string "Alvin|RM1200" has a length of 12+2, should I just increase the value in cx, or I initialise the cx again? – LIM WENG NI Sep 20 '22 at 05:42
  • @LIMWENGNI The DOS.WriteFile function does not modify the CX register. Therefore, for your next string that has 2 extra characters, you can freely choose between `add cx, 2` or `mov cx, 14`. Both these instructions have a 3-byte encoding. There's nothing to gain or loose from preferring one over the other. – Sep Roland Sep 24 '22 at 15:19