. : : Assembly Language : : .  |  首页  |  我提出的问题  |  我参与的问题  |  我的收藏  |  消息中心   |  游客  登录  | 
刷新 | 提问 | 未解决 | 已解决 | 精华区 | 搜索 |
  《汇编语言》论坛 ->外中断
  管理员: assembly   [回复本贴] [收藏本贴] [管理本贴] [关闭窗口]
主题 : :  对于帖子——“检测点15.1的一个疑问”中“再次pushf”问题的回复  [已解决] 回复[ 2次 ]   点击[ 490次 ]  
hky987654321
[帖 主]   [ 发表时间:2013-09-07 21:30 ]   [引用]   [回复]   [ top ] 
荣誉值:26
信誉值:0
注册日期:2013-07-15 09:25
先说结论,“再次pushf”是 必须的。该帖是lj9766 的帖子,很老了。提的问题非常好,非常有诱惑力!但却极易被忽视。其中回复已达10楼,然疑云犹存,我不想湮没其中,另辟一帖回复,以助惑者。lj9766在帖中认为,检测点15.1精简后,似乎连同pushf也不该要了。其实,只需将新编int 9这段的入栈与出栈过程一摆,立马澄清!看了下面的“简述”还不清楚,还可以接着看“详述”。

    (一)简述
     只简要、顺序地列出相关入栈与出栈,不含与问题无关的数据保护的入栈、出栈。
    1、由机器引发中断时,pushf 、push cs 、push ip
    2、由编程引发中断时,pushf 、push cs 、push ip (lj9766帖中质疑的就是这里的pushf该不该要)
    3、由原先int 9自带的iret返回指令,pop ip 、pop cs 、popf ,与2对应,完成对原先int 9的调用。
    4、由编程设置iret返回指令,pop ip 、pop cs 、popf ,与1对应,完成新编int 9。
    很清楚,在新编int 9中,引发原int 9之前,必须“ 再次pushf ”。

    (二)详述
    “两中断一外一内成嵌套,四首尾由你由它各同。”这是对书中281页,新int 9及其中嵌套的原int 9的概述。为方便表述,这两个一外一内嵌套的中断例程,居于外层的中断是新编的int 9,称为新int 9或外int 9;居于内层的是调用原先的int 9,称为原int 9或内int 9。中断例程的前部分称为首端,返回中断点的部分称为尾端,这样,书中新编写的int 9中断例程,依次就有“外首端”、“内首端”、“内尾端”、“外尾端”这四个部分。
     1、外首端:引发int 9中断的起点是键盘输入信息到达60h端口。这里要完成pushf 、If=0和TF=0设置、中断点cs:ip入栈以及新的cs:ip设置。这一过程是由机器引发,本来是为原int 9提供相关设置服务,但现在入口地址已改为指向新int 9,服务对象就成了新int 9。这里的入栈元素仅够下面的“外尾端”出栈。
    2、内首端:原int 9入口地址变更后,引发原int 9中断的起点是从编程指令call引导,并指向变更的入口地址开始的。而机器在这里已不发挥这一作用,只能完全人工编程模拟,所以call指令之前,必须再添加一个pushf。接着是设置If=0和TF=0(这一步可省,如作业处所讲)。然后才是call指令,使中断点cs:ip入栈,和修改cs:ip。这样,入栈元素刚好匹配下面的出栈操作。
    3、内尾端:可以肯定,原int 9包括iret返回指令,执行pop ip 、pop cs以及popf,这些出栈与内首端的入栈相对应。
    4、外尾端:属于新int 9中断,返回中断点的指令只能由编写的iret完成,即执行pop ip 、pop cs以及popf,这些出栈与外首端的入栈相对应。
    很清楚,在新编int 9中,call之前必须“ 再次pushf ”。
hky987654321
[第1楼]   [ 回复时间:2014-04-10 21:25 ]   [引用]   [回复]   [ top ] 
荣誉值:26
信誉值:0
注册日期:2013-07-15 09:25
回复:[贴 主]
------------------
结贴
hky987654321
[第2楼]   [ 回复时间:2014-04-10 21:25 ]   [引用]   [回复]   [ top ] 
荣誉值:26
信誉值:0
注册日期:2013-07-15 09:25
此贴由 贴主 于 [ 2014-04-10 21:25 ] 结贴。 结贴原因:问题已解决
得分情况:
此问题已结贴!
    Copyright © 2006-2024   ASMEDU.NET  All Rights Reserved