检测点 15.1
(1)精简代码
pushf
call dword ptr ds:[0]
- 将 IF 以及 TF 设置为0的代码如下,按照题意删除即可
; 把标志寄存器的内容放到 ax 里面
pushf
pop ax
; IF 以及 TF 为标志寄存器的第9位和第8位
; 这里只取高8位的AH寄存器,所以在末两位设0
; 使得 ax 中存放着修改好了的数据
and ah,11111100B
; 借由 ax 将修改好了的数据压入栈
push ax
; 从栈中弹出数据,送入标志寄存器
popf
; 至此,完成对标志寄存器 IF 以及 TF 位的修改
- pushf 以及 popf 参考
https://www.jianshu.com/p/94461cfddbc7
(2)不允许 发生中断
- 设置 int9 中断例程的段地址和偏移地址
cli ; TF = 0 不响应中断
mov word ptr es:[9*4],offset int9
mov es:[9*4+2],cs
sti ; TF = 1 可以响应中断
其实就是用 cli 以及 sti
将设置段地址以及偏移地址的指令【保护】起来
- 恢复 int9 中断例程的段地址和偏移地址
cli ; TF = 0 不响应中断
push ds:[0]
pop es:[9*4]
push ds:[2]
pop es:[9*4+2]
sti ; TF = 1 可以响应中断
完整源码
- 功能:在屏幕中间依次显示“a”~“z”,并可以让人看清,在显示的过程中,按下ESC键,改变显示的颜色。
assume cs:code
stack segment
db 128 dup (0)
stack ends
data segment
dw 0,0
data ends
code segment
start: mov ax,stack
mov ss,ax
mov sp,128
mov ax,data
mov ds,ax
mov ax,0
mov es,ax
push es:[9*4]
pop ds:[0]
push es:[9*4+2]
pop ds:[2]
cli ; TF = 0
mov word ptr es:[9*4],offset int9
mov es:[9*4+2],cs
sti ; TF = 1
mov ax,0B800H
mov es,ax
mov ah,'a'
s: mov es:[160*12+40*2],ah
call delay
inc ah
cmp ah,'z'
jna s
mov ax,0
mov es,ax
cli ; TF = 0
push ds:[0]
pop es:[9*4]
push ds:[2]
pop es:[9*4+2]
sti ; TF = 1
mov ax,4c00H
int 21H
delay: push ax
push dx
mov dx,0003H
mov ax,0
s1: sub ax,1
sbb dx,0
cmp ax,0
jne s1
cmp dx,0
jne s1
pop dx
pop ax
ret
int9: push ax
push bx
push es
in al,60H
pushf
pushf
pop bx
and bh,11111100B
push bx
popf
call dword ptr ds:[0]
cmp al,1
jne int9ret
mov ax,0B800H
mov es,ax
inc byte ptr es:[160*12+40*2+1]
int9ret: pop es
pop bx
pop ax
iret
code ends
end start
实际运行
检测点15.1 红色 S
检测点15.1 灰色 V