目录
- 13.1 int 指令
- 13.2 编写供应用程序调用的中断例程
- 13.3 对int、iret和栈的深入理解
- 13.4 BIOS和DOS所提供的中断例程
- 13.5 BIOS和DOS中断例程的安装过程
- 13.6 BIOS中断例程应用
- 13.7 DOS中断例程应用
- 实验13 编写、应用中断例程
中断信息可以来自CPU的内部和外部,当CPU的内部有需要处理的事情发生的时候,将产生需要马上处理的中断信息,引发中断过程。
13.1 int 指令
- int 指令的格式为:int n,n为中断类型码,它的功能是引发中断过程。CPU执行int指令过程如下:
- (1)取得中断类型码 n
- (2)标志寄存器入栈,IF=0,TF=0
- (3)CS、IP入栈
- (4)(IP)=(n 4),(CS)=(n4+2)
一般情况下,系统将一些具有一定功能的子程序,以中断处理程序的方式提供给应用程序调用。 我们在编程的时候,可以用int指令调用这些子程序。当然也可以自己写中断处理程序给别人调用。我们可以将中断处理程序简称为中断例程。
int 指令和call 指令的对比
int | call | |
---|---|---|
都跳转到子程序执行 | 子程序是中断处理程序,简称为中断例程 | 常见的子程序 |
如何得到子程序入口地址 | 根据中断类型码查找中断向量表 | 根据机器码中的位移或CS IP或保存在寄存器、内存中的CS IP |
跳转到子程序前要保存、设置哪些内容 | 保存标记寄存器、TF=0、IF=0,然后保存CS IP | 只要保存IP或CS IP |
保存在哪儿 | 保存在栈中 | 保存在栈中 |
如何返回 | 通常用iret指令返回 | 用ret或retf指令返回 |
int指令的最终功能和call指令相似,都是调用一段程序。上面我自己总结的对比表格比较重要。
13.2 编写供应用程序调用的中断例程
int指令和iret指令的配合使用与call指令和ret指令的配合使用具有相似的思路。编写中断例程和编写子程序的时候具有同样的问题,就是要避免寄存器冲突。应该注意例程中用到的寄存器的值的保存和恢复。
碰到程序我都要自己写一遍,这小节第二个程序,没看清需求就写了,写得比例题中更全面一点,字符串中包含非字母的字符能识别,不处理。写完这个程序挺得意的,虽然在高手眼中很简单。
13.3 对int、iret和栈的深入理解
这小节的例子就是用int指令模拟其它指令,如loop指令、jmp指令。书本中的知识比较简单,无非就是注意一下int指令对栈的操作。
我在思考解决这小节时,总结出我的一些问题。当我遇到一个问题时,不能一眼看出解决办法,就本能抗拒问题,担心解决不了问题,然后带着这种恐惧的心,不是平常心,更谈不上藐视问题的心态,去解决问题,更加人为的增加了自己解决问题的难度。其实从自学开始,我碰到了很多难题,都解决了,而且几乎都是第二天就解决了。
我总结自己解决问题的关键是,遇到问题的第一天,对问题不熟悉,又想解决问题就逼迫自己去分析问题,分析的过程中对问题本身,还有问题相关的知识也就熟悉了,有些问题在分析过程中就看出问题的本质,可能当天花半小时左右就解决了,难一点的问题第二天也解决了。第二天解决的关键就是,第一天对问题及问题相关的知识熟悉了,发现难题不难了,就能以一种平常心去思考问题,然后发现问题的本质,结合相关知识找到问题的答案。
我的解题过程中充满了不自信,遇到问题不能一眼看出答案,就觉得自己不如别人,就会产生恐惧,害怕自己不如别人,为了认可自己,证明自己不比别人差,就想着赶快解决问题,这反而就失去了解决问题需要的平常心,更加难以解决问题,进一步加深了自己内心的不自信、自卑。
我想提醒自己的是,学习到现在已经解决了很多问题了,我不是天才,是个普通人,所以遇到的问题也就是普通人能解决的问题,只需要不恐惧,以一种平常心去面对问题,就能解决。因为事实如此,我至今遇到的问题都解决了。要知道能一眼看出答案的都不能称为问题,问题就是要先熟悉问题,然后分析问题,了解问题相关知识点,最后用一颗平常心去找出问题的答案。着什么急呢。
第二点我害怕遇到问题,遇到问题意味着我的学习速度要降下来,总想着快点把想学的东西学完,然后把知识换成钱。
我想提醒自己的第二点就是,知识之所以值钱,是因为学习的过程中需要停下来思考,真正值钱的就是思考的部分。如果把一本书读一遍就掌握了知识,那知识不稀缺,也不值钱。
我今后要做的就是,从遇到问题开始,自信的以一种平常心,去熟悉问题,分析问题,找出问题的本质,然后解决问题。不追求解题速度,追求自信从容,说不定比追求速度更快、更顺利的解决问题。
13.4 BIOS和DOS所提供的中断例程
- BIOS中主要包含以下几部分内容:
- (1)硬件系统的检测和初始化程序
- (2)外部中断和内部中断的中断例程
- (3)用于对硬件设备进行I/O操作的中断例程
- (4)其它和硬件系统相关的中断例程
从操作系统的角度看,DOS的中断例程就是操作系统向程序员提供的编程资源。 程序员在编程时可以用int指令直接调用BIOS和DOS提供的中断例程,来完成某些工作。和硬件设备相关的DOS中断例程中,一般都调用了BIOS的中断例程。
读这小节时,我误把书中介绍BIOS内容的内部中断例程、外部中断例程、对硬件设备进行IO操作的中断例程,看成是中断例程的分类了。纠结了很久,这里其实不强调分类,只是说明BIOS中包含的内容。如果非要分类的话,从CPU内外的角度来分,CPU内部引发的中断,就是内部中断/软件中断。包括异常(异常是CPU执行可能引发的问题);CPU外部引发的中断叫外部中断/硬件中断,包括IO中断。可以对硬件设备进行IO操作的中断例程,内部中断,外都中断都有。不能看成一个分类。
13.5 BIOS和DOS中断例程的安装过程
对于BIOS提供的中断例程,只需将入口地址登记在中断向量表即可,因为它们是固化到ROM中的程序,一直在内存中存在。
BIOS这个软件程序是硬件出厂时就安装好的,是最基础的软件系统;DOS等操作系统终端用户可以自己安装或更换操作系统,相对于BIOS来说属于后天安装的。而且操作系统的安装,需要有BIOS这个基本输入输出系统才能安装。
13.6 BIOS中断例程应用
一般来说,一个供程序员调用的中断例程中往往包含多个子程序,中断例程内部用传递进来的参数决定执行哪个子程序。 BIOS和DOS提供的中断例程,都用ah来传递内部子程序的编号。
- int 10h中断例程是BIOS提供的中断例程,其中包含了多个和屏幕输出相关的子程序。
- ah=2 表示调用第10h号中断例程的2号子程序,功能为设置光标位置,可以提供光标所在的行号、列号,和页号作为参数
- ah=9 表示调用第10h号中断例程的9号子程序,功能为在光标位置显示字符,可以提供要显示的字符、颜色属性、页号、字符重复个数作为参数。
13.7 DOS中断例程应用
- int 21h 中断例程是DOS提供的中断例程,其中包含了DOS提供给程序员在编程时调用的子程序。
- ah=4ch 表示调用第21h号中断例程的4ch号子程序,功能为程序返回,可以提供返回值作为参数
- ah=9 表示调用第21h号中断例程的9号子程序,功能为在光标位置显示字符串, 要显示的字符串需用“$”作为结束符,可提供字符串的地址作为参数。
实验13 编写、应用中断例程
- 前面两个实验,很简单,关键就是第三个实验,书中也要求我们细细体会其中的编程思想,下面是我的一些理解:
- (1)本来想写“offset不支持在数据段和栈段中使用的”,因为我看到此刻offset都只在代码段中使用,我觉得不可能这么傻,后来查了资料,发现可以在其他段中用offset,甚至于要求就是这么写的,这样数据段、栈段、代码段才能结构分明,本书后面第16章就介绍了offset在更全面的应用。
- (2)某些看似可以利用循环指令的需求,循环体的规律可能不直接,我们需要创造出规律。这里类似高级语言的指针、间接指针相关知识。