.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