汇编语言(王爽第三版)检测点15

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

汇编语⾔(王爽第三版)检测点15
检测点 15.1
(1)仔细分析⼀下上⾯的int 9中断例程,看看是否可以精简⼀下?
其实在我们的int 9中断例程中,模拟int指令调⽤原int 9中断例程的程序段是可以精简的,因为在进⼊中断例程后,IF和TF都已经置零,没有必要再进⾏设置了。

对于程序段:
pushf ;将寄存器值⼊栈
pushf ;将寄存器值⼊栈
pop ax ;弹栈到ax中,(ax)=(flag)
and ah, 11111100b ;注意是⾼8位,IF和TF是标志位中的第9和第8位,按位与
push ax ;将修改后的值⼊栈。

popf ;将修改后的值弹栈到标准寄存器中。

这时IF=0,TF=0
call word ptr ds:[0];调⽤原来的int9中断例程。

可以精简为:
 pushf
 call word ptr ds:[0] 
两条指令。

程序分析:
【1】由于我们⽆论是调⽤那个中断处理例程,CPU都⼲如下的活:
(1)从中断信息中取得中断类型码
(2)标志寄存器⼊栈保存(因为在中断过程中要改变标志寄存器的值。


(3)设置标志寄存器的第8位TF(跟踪标志)和第9位IF(中断标志)为0.(防⽌单步中断和其他外部中断发⽣)
(4)cs的内容⼊栈
(5)IP的内容⼊栈
(6)设置ip的值为:N(中断类型码)*4;设置cs的值:N*4+2
所以第⼆个pushf是多余的指令,然后是设置IF和TF的指令也是多余的了。

【2】为什么还有个pushf呢,这个pushf指令压栈标志寄存器,确实是保护标志寄存器的值,也是为了与中断程序中的iret(它内部CPU操作步骤有popf)相呼应。

如果没有这个pushf,那么iret指令执⾏中出栈到标准寄存器的值可能不正确了。

(2)仔细分析上⾯程序中的主程序,看看有什么潜在的问题?
在主程序中,如果在执⾏设置int 9中断例程的段地址和偏移地址的指令之间,发⽣了键盘中断,则CPU将转去⼀个错误的地址执⾏,将发⽣错误。

找出这样的程序段,改写它们,排除潜在的问题。

提⽰:注意sti和cli指令的⽤法。

程序分析:
【1】关于设置中断向量表的指令,在程序中就2段。

mov word ptr es:[9*4], offset int9
mov es:[9*4+2], cs ;将新的int9⼊⼝地址写⼊中断向量表中
---
; 将中断向量回写回中断向量表中
mov ax, 0
mov es, ax ;将es指向0000段内存中断向量表
push ds:[0]
pop es:[9*4]
push ds:[2]
pop es:[9*4+2]
如果在指令执⾏在这2段中间,引发了键盘中断事件,由于正在设置中断向量表,故(ip)和(cs)值可能不确定。

为了避免这2段代码不受到中断事件的⼲扰,将中断屏蔽了。

【2】sti和cli指令的⽤法:
cli 禁⽌中断发⽣
sti 允许中断发⽣
【3】这⼆段代码前后加上cli和sti指令即可:
;在中断向量表中设置新的中断⼊⼝地址的时候不让其发⽣中断
cli
mov word ptr es:[9*4],offset int9
mov word ptr es:[9*4+2],cs
sti
恢复中断向量表int9的源地址时:
cli
push ds:[0]
pop es:[9*4]
push ds:[2]
pop es:[9*4+2]
sti。

相关文档
最新文档