昨天遇到一个80x86汇编语言程序在DOS下无法正常运行,而在DEBUG里却可以的问题。
出错的程序代码如下:
DATA SEGMENT
string DB 100
DB ?
DB 100 DUP(?)
M DB ?
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA
START:
MOV AX,DATA
MOV DS,AX
MOV m,00H
MOV bX,OFFSET string
MOV AH,10
INT 21H
call disp
MOV Cl,byte ptr [BX]+1
MOV CH,0
add bx,2
XUNH: MOV AL,byte ptr [BX]
CMP AL,20H
JNZ NEXT
INC byte ptr M
NEXT: INC BX
LOOP XUNH ;循环(隐含CX)
ADD byte ptr M,30H
MOV DL,byte ptr M
MOV AH,2
INT 21H
MOV AH,4CH
INT 21H
disp PROC
push dx
push ax
MOV DL,0DH ;回车换行
MOV AH,2
INT 21H
MOV DL,0AH
MOV AH,2
INT 21H
pop ax
pop dx
RET
disp ENDP
CODE ENDS
END START
该程序在DOS下运行的情况,如下图1所示。
图1 在DOS下的运行情况截图
奇怪的是,在debug里调试运行此程序时,结果是正确的。见下图2所示。
图2 上面的程序在DEBUG里调试运行的结果
仔细分析上面的源程序,结果发现,第15行的语句:MOV bX,OFFSET string有错。该语句是DOS功能调用(10号)的入口参数初始化指令。目标寄存器用错了,应该是DX。
那为什么上面的程序尽管使用了错误的入口参数,在DEBUG里调试时,结果是正确的呢?我的答案是,在调试过程中,该功能调用还是取的DX的值。调试时,DX的值刚好是跟BX的值是一样的,所以,结果是正确的。而直接在DOS下运行该程序时,DX寄存器的结果,不一定正好跟BX的值一样。于是,出现了上面的问题。至此,上面的汇编程序,只需修改这一条指令,将它改为:MOV DX,OFFSET string,程序即可正常运行了。