来源于杨季文T6-6C.ASM。
CR = 0DH
LF = 0AH
ESCAPE = 1BH
;
CSEG SEGMENT
ASSUME CS:CSEG, DS:CSEG
OLD1BH DD ?
OLD16H DD ?
;
NEWKEY PROC FAR
NEW16H: CMP AH, 10H
JZ PKEY
CMP AH, 11H
JZ PKEY2
CMP AH, 1
JZ PKEY2
OR AH, AH
JZ PKEY
JMP DWORD PTR CS:OLD16H
;
PKEY: PUSH AX
PKEY1: POP AX
PUSH AX
PUSHF ; 求解为什么要pushf 如果下面AL=3(表示按下ctrl+c)时,就pop ax ,ax=flag了,flag感觉值不确定,有什么参考 意义
CALL DWORD PTR CS:OLD16H
CMP AL, 3
JZ PKEY1
CMP AX, 0300H
JZ PKEY1
ADD SP, 2
IRET
;
PKEY2: PUSH AX
PKEY3: POP AX
PUSH AX
PUSHF
CALL DWORD PTR CS:OLD16H
JZ PKEY6
CMP AL, 3
JZ PKEY4
CMP AX, 0300H
JNZ PKEY5
;
PKEY4: XOR AH, AH
PUSHF
CALL DWORD PTR CS:OLD16H
JMP PKEY3
;
PKEY5: ADD SP, 2
CMP AX, 0300H
RET 2
PKEY6: ADD SP, 2
CMP AX, AX
RET 2
NEWKEY ENDP
NEW1BH: IRET
;
START: PUSH CS
POP DS
MOV AX, 3516H
INT 21H
MOV WORD PTR OLD16H, BX
MOV WORD PTR OLD16H+2, ES
;
MOV AX, 351BH
INT 21H
MOV WORD PTR OLD1BH, BX
MOV WORD PTR OLD1BH+2, ES
;
MOV DX, OFFSET NEW16H
MOV AX, 2516H
INT 21H
MOV DX, OFFSET NEW1BH
MOV AX, 251BH
INT 21H
;
CONT: MOV AH, 8
INT 21H
CMP AL, ESCAPE
JZ SHORT XIT
MOV DL, AL
MOV AH, 2
INT 21H
CMP DL, CR
JNZ CONT
MOV AH, 2
INT 21H
MOV DL, LF
MOV AH, 2
INT 21H
JMP CONT
XIT: LDS DX, OLD1BH
MOV AX, 251BH
INT 21H
LDS DX, CS:OLD16H
MOV AX, 2516H
INT 21H
MOV AH, 4CH
INT 21H
CSEG ENDS
END START
------解决方案--------------------------------------------------------
pushf 是和下一个指令 CALL DWORD PTR CS:OLD16H 联合着用的,转去原 int16h 中断,这样中断最后的 iret 才能正常返回并且保持堆栈平衡,和后续的 pop ax 并没有关系,它被原 int16h 里最后的 iret 给出栈了。