我在TASM 64位Windows 10中比较两个值时遇到麻烦。我试图显示文件的最后N行(我没有包含所有代码但假设文件处理正确,我可以提供完整代码如果需要)所以我创建了一个从输入读取N的过程(READN)。
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
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'
。现在你可以wrirte
MOV AX, LINES
SUB AX, N
MOV N, AX
之前失败了,因为读取的代码在N变量中的高字节为1。在上述countline减法之后,这又产生了一个非常大的新N.这就是打印从未发生过的原因! 做出两个修正,你会发现它不再失败......
如果在源文件的开头添加指令IDEAL,然后将所有命令替换为具有明确声明的“偏移”或方括号值的立即值,则可以解决所有问题。如果你当然使用borland turbo汇编程序。