汇编程序(TASM)比较的麻烦

问题描述 投票:2回答:2

我在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
assembly dos x86-16 tasm
2个回答
1
投票

readn

MOV  AH, 1
INT  21H
MOV  N, AX

这个DOS函数返回一个字符!你需要这个价值。更好写

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

由于早期的错误,这里需要ADD AX, '0'。现在你可以wrirte

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

displaylines

之前失败了,因为读取的代码在N变量中的高字节为1。在上述countline减法之后,这又产生了一个非常大的新N.这就是打印从未发生过的原因! 做出两个修正,你会发现它不再失败......


0
投票

如果在源文件的开头添加指令IDEAL,然后将所有命令替换为具有明确声明的“偏移”或方括号值的立即值,则可以解决所有问题。如果你当然使用borland turbo汇编程序。

© www.soinside.com 2019 - 2024. All rights reserved.