SickBoi
SickBoi

Reputation: 23

troubles with assembler(TASM) comparison

I am having troubles with comparing two values in TASM 64-bit Windows 10. I am trying to display last N lines of a file (I didn't include all the code but assume that the file handling is correct, I can provide full code if needed) so I created a procedure(READN) which reads N from input.

N          DW   3
LINES      DW   0

READN PROC NEAR

      MOV  AX, @DATA
      MOV  DS, AX
      MOV  DI, N
      MOV  AH, 1
      INT  21H
      MOV  N, AX
      XOR  AX, AX
      MOV  AX, N
      MOV  DX, AX
      MOV  AH, 2
      INT  21H
      RET
READN ENDP

I then count the number of lines in given file in procedure COUNTLINES by incrementing LINES each time there is a '\n' or

COUNTLINES PROC NEAR

      MOV  AH,3FH         ;read from file function
      MOV  BX,HANDLE      ;load file handle
      LEA  DX,FBUFF       ;set up pointer to data buffer
      MOV  CX,1           ;read one byte
      INT  21H            ;DOS call
      CMP  AX,0           ;were 0 bytes read?
      JZ   EOFF           ;yes, end of file found
      MOV  DL,FBUFF       ;no, load file character
      CMP  DL,1AH         ;is it Control-Z <EOF>?
      JZ   EOFF           ;jump if yes
      CMP  DL,0AH         ;is it \n ?
      JZ   INCR           ;jump if yes
      JMP  COUNTLINES       ;and repeat
      MOV  AH,9           ;display string function
      INT  21H            ;DOS call
      STC                 ;set error flag

EOFF:     inc DS:[LINES]
      XOR AX, AX
      MOV AX, LINES
      ADD AX, '0'
      SUB AX, N
      MOV N, AX
      MOV LINES, 0
      MOV AX, N
      MOV DX, AX
      MOV AH, 2
      INT 21H
      CALL CLOSEFILE
      CALL OPENFILE
      RET

INCR:     INC DS:[LINES]
      JMP COUNTLINES
COUNTLINES ENDP

And finally the problem I am having is in the DISPLAYLINES procedure where I again increment LINES from zero but this time, when LINES euqals N I start printing out the lines. The problem is, my compare (in the INCREM: part) doesn't work as I expected and when I try to compare N and LINES (I first move LINES to AX), the program just never jumps to the desired function even though the values should be equal at some point. If you could try to find why this is happening or possibly even provide a fix I would be very grateful.

DISPLAYLINES PROC NEAR

      MOV  AH,3FH         ;read from file function
      MOV  BX,HANDLE      ;load file handle
      LEA  DX,FBUFF       ;set up pointer to data buffer
      MOV  CX,1           ;read one byte
      INT  21H            ;DOS call
      CMP  AX,0           ;were 0 bytes read?
      JZ   EOF           ;yes, end of file found
      MOV  DL,FBUFF       ;no, load file character
      CMP  DL,1AH         ;is it Control-Z <EOF>?
      JZ   EOF           ;jump if yes
      CMP  DL,0AH         ;is it \n ?
      JZ   INCREM           ;jump if yes
      JMP  DISPLAYLINES       ;and repeat

EOF:      RET

INCREM:   INC  DS:[LINES]
      MOV  AX, LINES
      CMP  AX, N
      JZ   PRINT
      JMP  DISPLAYLINES

PRINT:    MOV  AH,3FH         ;read from file function
      MOV  BX,HANDLE      ;load file handle
      LEA  DX,FBUFF       ;set up pointer to data buffer
      MOV  CX,1           ;read one byte
      INT  21H            ;DOS call
      CMP  AX,0           ;were 0 bytes read?
      JZ   EOF           ;yes, end of file found
      MOV  DL,FBUFF       ;no, load file character
      CMP  DL,1AH         ;is it Control-Z <EOF>?
      JZ   EOF           ;jump if yes
      MOV  AH,2           ;display character function
      INT  21H            ;DOS call
      JMP  PRINT       ;and repeat
DISPLAYLINES ENDP

Upvotes: 2

Views: 173

Answers (2)

Fifoernik
Fifoernik

Reputation: 9899

readn

MOV  AH, 1
INT  21H
MOV  N, AX

This DOS function returns a character! You need the value instead. Better write

MOV  AH, 1
INT  21H
sub  al, '0'
mov  ah, 0
MOV  N, AX

countlines

MOV AX, LINES
ADD AX, '0'
SUB AX, N
MOV N, AX

Here the ADD AX, '0' was somewhat needed because of the earlier error. Now you can just wrirte

MOV AX, LINES
SUB AX, N
MOV N, AX

displaylines

This failed before because the readn code had a high byte of 1 in the N variable. This in turn produced a very big new N after the above countlines subtraction. That's why the printing never occurred!
Make both corrections and you'll see it doesn't fail anymore...

Upvotes: 1

Aahz Brut
Aahz Brut

Reputation: 1

If you add directive IDEAL in the beginning of your source file and then replace all commands with immediate values with explicitly stated 'offset' or square bracketed values - you resolve all of your problems. If of course you're using borland turbo assembler.

Upvotes: 0

Related Questions