Assembly 汇编程序(TASM)比较的问题
我在比较TASM 64位Windows 10中的两个值时遇到问题。我试图显示文件的最后N行(我没有包括所有代码,但假设文件处理是正确的,如果需要,我可以提供完整的代码),因此我创建了一个从输入读取N的过程(READN)Assembly 汇编程序(TASM)比较的问题,assembly,dos,x86-16,tasm,Assembly,Dos,X86 16,Tasm,我在比较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 21
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
然后,我在过程COUNTLINES中通过每次有“\n”或“\n”时增加行数来计算给定文件中的行数
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
COUNTLINES PROC NEAR
MOV-AH,3FH;从文件读取函数
MOV BX,手柄;加载文件句柄
LEA DX,FBUFF;设置指向数据缓冲区的指针
MOV-CX,1;读取一个字节
INT 21H;待命
CMP-AX,0;是否读取了0字节?
JZ-EOFF;是,找到文件结尾
MOV-DL,FBUFF;否,加载文件字符
CMP-DL,1AH;是Control-Z吗?
JZ-EOFF;如果是,跳转
CMP-DL,0AH;是吗?
JZ增量;如果是,跳转
JMP计数线;重复
MOV-AH,9岁;显示字符串函数
INT 21H;待命
STC;设置错误标志
EOFF:inc DS:[行]
XOR AX,AX
MOV-AX,线路
添加AX,“0”
分斧
MOV N,AX
MOV线,0
莫瓦克斯,N
MOV-DX,AX
MOV啊,2
INT 21H
调用CLOSEFILE
调用OPENFILE
RET
INCR:INC DS:[行]
JMP计数线
计数线ENDP
最后,我遇到的问题是在DISPLAYLINES过程中,我再次从零开始增加行数,但这次,当行数为N时,我开始打印行数。问题是,我的比较(在INCREM:part中)没有像我预期的那样工作,当我尝试比较N和行(我首先将行移动到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
DISPLAYLINES PROC NEAR
MOV-AH,3FH;从文件读取函数
MOV BX,手柄;加载文件句柄
LEA DX,FBUFF;设置指向数据缓冲区的指针
MOV-CX,1;读取一个字节
INT 21H;待命
CMP-AX,0;是否读取了0字节?
JZ-EOF;是,找到文件结尾
MOV-DL,FBUFF;否,加载文件字符
CMP-DL,1AH;是Control-Z吗?
JZ-EOF;如果是,跳转
CMP-DL,0AH;是吗?
JZ增量;如果是,跳转
JMP显示线;重复
EOF:RET
增量:INC DS:[行]
MOV-AX,线路
化学机械抛光
JZ打印
JMP显示行
打印:MOV AH,3FH;从文件读取函数
MOV BX,手柄;加载文件句柄
LEA DX,FBUFF;设置指向数据缓冲区的指针
MOV-CX,1;读取一个字节
INT 21H;待命
CMP-AX,0;是否读取了0字节?
JZ-EOF;是,找到文件结尾
MOV-DL,FBUFF;否,加载文件字符
CMP-DL,1AH;是Control-Z吗?
JZ-EOF;如果是,跳转
MOV-AH,2;显示字符功能
INT 21H;待命
JMP打印;重复
显示行ENDP
如果在源文件的开头添加理想指令,然后将所有命令替换为立即值,并使用明确说明的“偏移量”或方括号中的值,则可以解决所有问题。当然,如果您使用的是borland turbo assembler。readn
此DOS函数返回一个字符!您需要的是值。最好写
MOV AH, 1
INT 21H
sub al, '0'
mov ah, 0
MOV N, AX
计数线 由于前面的错误,
addax,'0'
在这里有些必要。现在你就可以扭动了
MOV AX, LINES
SUB AX, N
MOV N, AX
显示线 这之前失败,因为readn代码在N变量中有一个高字节1。这反过来又产生了一个非常大的新N后,上述countlines减法。这就是为什么印刷从未发生过
进行两次更正,您将看到它不再失败…文件打开了吗?阅读成功吗?
INCREM
真的被调用了吗?是的,是的,我不明白第三个问题这个意大利面代码中有很多错误。您的问题主要基于READN
中的MOV N,AX
。在AL
中返回结果ASCII字符,在AH
中返回随机值。因此,在movn,AX之前放置一个xor ah,ah。也许今晚我能写一个完整的答案。@rkhb这真的是一个意大利面代码:DD我对汇编很陌生,所以请容忍我。我一定会试试你的建议。
MOV AX, LINES
ADD AX, '0'
SUB AX, N
MOV N, AX
MOV AX, LINES
SUB AX, N
MOV N, AX