鱼C论坛

 找回密码
 立即注册
查看: 4024|回复: 2

[学习笔记] 第十二章 内中断

[复制链接]
发表于 2017-12-1 09:47:27 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 若余相思 于 2017-12-1 09:47 编辑

中断信息的含义:CPU在执行完当前正在执行的的指令之后,检测从CPU外部发来或内部产生的一种特殊的信息,
并且立即对所收到的信息进行处理


12.1节   中断的产生

当CPU有如下的情况发生时,将产生相应的中断信息

(1)除法错误
(2)单步执行
(3)执行into指令
(4)执行int指令

中断信息包含中断类型码,该码为一个字节数据类型,可以表述256种中断信息。比如除法错误的类型码是0


12.3节   中断向量表

中断必须要找到中断的地址来说设置CS和IP,然而去哪找呢?

中断向量表保存着256个中断源所对应的中断处理程序的入口地址

中断向量表存放在内存中,从0开始,从0000:0000到0000:03FF的1024个单元的中存放着中断向量表,不能存放在别处

中断处理程序的入口地址包括段地址和偏移地址,故一个表项中占两个字。高地址存放段地址,地址地存放偏移地址。

从而可以得知,存储N号中断源的中断处理程序入口的偏移地址为4N,段地址为4N + 2


12.4节   中断过程

中断在接收到中断的入口地址时,必须先保存原来的CS和IP以便恢复到原来的状态

中断的过程:
(1)取得中断类型码(从中断信息中获取)
(2)将标志寄存器的值入栈
(3)设置标志寄存器的第8位TF和第9位的IF的值位0
(4)CS入栈
(5)IP入栈
(6)将中断类型码N*4和N*4 + 2的两个字单元读取的中断处理程序入口地址设置为IP和CS

用更简洁的描述就是:
(1)取得中断类型码
(2)pushf
(3)TF = 0 和IF = 0
(4)push CS
(5)push ip
(6)(IP) = (N * 4) CS = (N * 4 + 2)

12.5节   中断处理程序和iret指令

由于CPU随时都要检测中断信息,所以中断处理程序必须一直存储在内存的某段空间中

中断处理程序的编写过程
(1)保存中断过程用到的寄存器
(2)处理中断
(3)恢复用到的寄存器
(4)用iret指令

iret指令用汇编描述为:
pop IP
pop CS
popf

由可以看出入栈时必须是先pushf,然后push CS,最后到IP

12.7节~12.10节  编程处理0号中断

按照书里面的套路就是:
(1)首先将中断的程序代码移动到0000:0200H处(利用movsv命令)
(2)然后将中断程序写出来(就是在屏幕显示字符的程序)
(3)注意将要显示的字符串放在0000:0200H处,这是因为数据段的信息会因为程序的结束而释放掉,然后被别的信息覆盖
但在0000:0200H的中断代码却一直保留着,因为中断是一直在监听的,当再次发生中断时,将显示字符串的不是你想要的信息。
故要将数据段的内容放在一段安全的地方
(4)最后就是修改中断向量表了

这里放上完成的代码(亲测可行哦)

  1. assume cs: code

  2. code segment

  3. start:         mov ax, cs
  4.                         mov ds, ax
  5.                         mov si, offset do0
  6.                        
  7.                         mov ax, 0
  8.                         mov es, ax
  9.                         mov di, 200H
  10.                        
  11.                         mov cx, offset do0end-offset do0
  12.                        
  13.                         cld
  14.                         rep movsb
  15.                        
  16.                         mov ax, 0
  17.                         mov es, ax
  18.                         mov word ptr es:[0*4],200H
  19.                         mov word ptr es:[0*4+2], 0
  20.                        
  21.                         mov ax, 4c00H
  22.                         int 21H
  23.                        
  24.                        
  25.         do0:        jmp short do0start
  26.                         db "overflow!"
  27.                        
  28. do0start:        mov ax, cs
  29.                                 mov ds, ax
  30.                                 mov si, 202H
  31.                                
  32.                                 mov ax, 0b800H
  33.                                 mov es, ax
  34.                                 mov di, 12*160+72
  35.                                
  36.                                 mov cx, 9
  37.                         s: mov al, [si]
  38.                                 mov es:[di], al
  39.                                 inc si
  40.                                 add di, 2
  41.                                
  42.                                 loop s
  43.                                
  44.                                 mov ax, 4c00H
  45.                                 int 21H
  46.                        
  47. do0end:        nop
  48. code ends
  49. end start
  50.                        
复制代码


12.11节   单步中断

单步中断的类型码是:1

当TF标志位为1的时候将引发单步中断

debug每次执行完t时将显示寄存器的信息,利用的就是单步中断

为了不让单步中断陷入单步中断的死循环,每次单步中断之前都将TF为设置为0,我猜想其他中断也是要如此吧^_^


12.12节   响应中断的特殊情况


当执行压栈指令时将不引发中断过程,因为压栈过程是连续设置ss和sp的,这时引发中断将引发sp的不一致,从而导致错误

本帖被以下淘专辑推荐:

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2017-12-2 21:10:15 | 显示全部楼层
问一下
30.  do0start:        mov ax, cs
31                                mov ds, ax
32                                mov si, 202H
第32行为何默认ds是0,直接取si为202H
ds为何不能选择其他值,例如0020,si:0
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-12-3 00:46:24 | 显示全部楼层
宁静致远苏铭 发表于 2017-12-2 21:10
问一下
30.  do0start:        mov ax, cs
31                                mov ds, ax

你想一下,我的中断处理程序在0:200h处,我的CS和IP就要分别是0和200H
我的字符串overflow!在段地址为0,偏移地址为202H处,所以ds只能置为0,si只能置为202H啊
如果取了你写的值,那指向就不是overflow!了 ^_^
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-6-9 18:05

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表