汇编程序(TASM)比较遇到麻烦

时间:2019-03-15 16:45:14

标签: assembly dos x86-16 tasm

我在比较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

2 个答案:

答案 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汇编程序。