21,489
社区成员




为什么我书写的汇编程序会把end后面的指令也给执行?
DATA SEGMENT USE16
CRLF DB 0DH,0AH,'$'
BUF1 DB 50
DB 0
DB 50 DUP(0)
BUF2 DB 50
DB 0
DB 50 DUP(0)
RES1 DB 'MATCH!$'
RES2 DB 'NO MATCH !$'
DATA ENDS
STACK SEGMENT USE16 STACK
DB 200 DUP(0)
STACK ENDS
CODE SEGMENT USE16
ASSUME DS:DATA,SS:STACK,CS:CODE
START: MOV AX,DATA
MOV DS,AX
LEA DX,BUF1 ;输入buf1
MOV AH,10
INT 21H
LEA DX,CRLF ;换行
MOV AH,9
INT 21H
LEA DX,BUF2 ;输入buf2
MOV AH,10
INT 21H
LEA DX,CRLF ;换行
MOV AH,9
INT 21H
MOV CL,BUF1+1
MOV CH,BUF2+1
CMP CL,CH ;比较buf1和buf2长度
JNE NOMATCH
MOV BX,2
LOOPA: MOV AL,BUF1[BX] ;循环判断buf1和buf2中字符是否相同
MOV AH,BUF2[BX]
CMP AL,AH
JNE NOMATCH
INC BX
DEC CL
JNZ LOOPA
LEA DX,RES1
MOV AH,9
INT 21H
JMP EXIT
NOMATCH:LEA DX,RES2
MOV AH,9
INT 21H
EXIT: NOP
CODE ENDS
END START
理论上nop是代码的最后一句,但是在td调试的时候可以运行到nop下面的指令,是代码有问题吗?
你应该在END之前写两句:
MOV AX,4C00H
INT 21H
这个,不是代码的问题,是 dos系统运行程序机制的缺陷。
那些,其实并不是你的汇编程序 END 语句之后的内容,尽管你的源程序在 END 后并没有东西,不管有没有,都不会出现在后来的 exe 可执行程序里的。那些,只是内存里的随机数据,多可能是之前运行的程序的遗迹;程序运行结束后,dos 并不对其曾经占用过的内存进行清理(现在流行的 windows各版本也没有吧),所以保留着之前的样子;对程序的运行,无论是代码还是数据,dos都没有访问范围的检验核查和控制机制,所以,可以随意到任意的地方,只要代码乐意或有bug,更不用说调试软件里可以随意手工修改 cs:ip 及其它任意的寄存器了。