Reputation: 23
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
Reputation: 9899
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
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
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
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