我在比较TASM 64位Windows 10中的两个值时遇到麻烦。我试图显示文件的最后N行(我没有包括所有代码,但假设文件处理正确,我可以提供完整的代码(如果需要的话)。因此我创建了一个过程(READN),该过程从输入中读取N。
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
然后我通过在每次有'\ n'或
时增加LINES来计数过程COUNTLINES中给定文件的行数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
最后我遇到的问题是在DISPLAYLINES过程中,我再次从零开始增加LINES,但是这一次,当LINES euqals N时,我开始打印行。问题是,我的比较(在INCREM:部分)没有按预期工作,并且当我尝试比较N和LINES(我首先将LINES移到AX)时,即使在某些时候值应该相等。如果您能找到原因,甚至可以提供解决方法,我将不胜感激。
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
答案 0 :(得分:1)
MOV AH, 1 INT 21H MOV N, AX
此DOS函数返回一个字符!您需要该值。写得更好
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
由于先前的错误,这里有点需要ADD AX, '0'
。现在你可以写
MOV AX, LINES
SUB AX, N
MOV N, AX
此操作之前失败,因为 N 变量中 readn 代码的高字节为1。在上述 countlines 减法之后,这反过来又产生了非常大的新 N 。这就是为什么从未进行过打印的原因!
进行两次更正,您将看到它不再失败...
答案 1 :(得分:0)
如果在源文件的开头添加指令IDEAL,然后将所有命令替换为具有明确声明的“偏移”或方括号值的立即数,则可以解决所有问题。当然,如果您使用的是Borland Turbo汇编程序。