.286 CODE SEGMENT ASSUME CS:CODE,DS:CODE ORG 100H START: JMP INSTALL D_MES1 DB 'CS:IP = %04h:%04h %,FLAG = %017b%,',0DH,0AH,0 DW _CS,_IP,_FLAG _CS DW ? _OLD_CS DW ? _IP DW ? _FLAG DW ? D_MES2 DB '%14r- SEGMENT CHANGE %13r-',0DH,0AH,0 ;新的单步中断 INT 1 例程 ; INT1: PUSH AX PUSH BP MOV BP,SP ; MOV AX,SS:[BP+4] ;返回的 ip MOV CS:_IP,AX MOV AX,SS:[BP+6] ;返回的 cs MOV CS:_CS,AX MOV AX,SS:[BP+8] ;flag MOV CS:_FLAG,AX POP BP POP AX PUSHF PUSHA PUSH DS PUSH ES PUSH CS POP DS PUSH CS POP ES MOV AX,_CS CMP AX,_OLD_CS MOV _OLD_CS,AX JZ INT1_1 MOV SI,OFFSET D_MES2 ;segment has changed CALL PRINTF INT1_1: MOV SI,OFFSET D_MES1 ;print return address CALL PRINTF ;and flags POP ES POP DS POPA POPF IRET INSTALL: MOV AX,CS MOV _OLD_CS,AX MOV AX,3501H ;keep int 01 INT 21H PUSH ES PUSH BX MOV AX,2501H ;set new int 01 MOV DX,OFFSET INT1 INT 21H PUSHF POP AX OR AX,0100H PUSH AX POPF ;set int 01 flag ;-------------------------------------------------------- XOR AX,AX MOV ES,AX ;从这一句开始单步中断 MOV AH,-1 ;由于 INT 语句要清单步中断,所以 PUSHF ;要用 PUSHF/CALL FAR 的形式执行 INT 21H CALL DWORD PTR ES:[4*21H] PUSHF POP AX AND AX,0FEFFH PUSH AX ;跟踪完毕后清楚单步中断 POPF ;clear int 01 flag ;--------------------------------------------------------- POP DX POP DS MOV AX,2501H INT 21H ;restore old int 01 INT 20H INCLUDE PRINTF.ASM ;公用屏幕输出子程序 CODE ENDS END START