原文:  IDT系列:(一)初探IDT,Interrupt Descriptor Table,中断描述符表

IDT,Interrupt Descriptor Table,中断描述符表是CPU用来处理中断和程序异常的。

一、有关IDT的基本知识

1、中断时一种机制,用来处理硬件需要向CPU输入信息的情况。 比如鼠标,键盘等。

2、中断和异常的产生是随机的,在CPU正常运行过程中随时可能产生。CPU的中断处理机制

3、中断可以由硬件产生(称为外部中断),也可以由软件产生(称为内部中断),在程序中写入int n指令可以产生n号中断和异常(n从0-ffh)。

4、同时CPU的中断异常机制还是重要特性的支持原理,比如程序调试,程序运行过程中的异常处理(如零除数异常、内存分页错误等)。

5、早期的操作系统甚至是通过中断来进行内核调用的。int指令是一种c从ring3 进入ring 0的方法。比如windows在xp版本之前使用的int 2e。在x86 CPU提供了sysenter指令后,这种方式才被放弃。

6、每一种中断对应一个中断号。CPU执行中断指令时,会去IDT表中查找对应的中断服务程序(interrupt service routine ,ISR)。ISR(为了表述方便后面用ISR n表示n号中断的处理程序),x86CPU最大可以支持256种中断。

7、中断是CPU的机制,不管运行的是什么操作系统,只有是运行于x86架构,IDT结构式必然存在的。IDT表中的ISRs应该有操作系统提供。

8、异常分为错误(Faults)、陷阱(Traps)和终止(Aborts)三种,其区别是“错误”允许产生错误的程序继续允许,“陷阱”也可以,但是“错误”产生于指令执行后,而“陷阱”需要在产生异常的指令执行后,因此从“错误”中返回时继续执行产生错误的指令,而从“陷阱返”回时应当从产生异常的指令后开始执行。终止产生时,处理程序不能得到精确的异常产生的代码位置,程序不能继续进行,硬件错误会产生“终止”。 例如page faults就是一个faults,mov [eax], ecx,产生了一个分页错误,表面[eax]内存是无效,需要先进行分页处理从新映射物理内存然后才能继续进行mov操作;而断点是一个Trap。

9、Intel指定或保留了前32个中断号的作用,操作系统可以指定其余的中断号的作用。

10、中断的过程中可以产生新的中断。中断时有优先级的,高优先级的中断可以“中断”低优先级的中断。有的ISR不能被中断,可以使用STI (set interrupt-enable flag) and CLI(clear interrupt-enable flag)设置IF标志来启动和关闭中断。

(更详细的内容可以参考Intel® 64 and IA-32 Architectures Software Developer’s Manual

二、IDT表的结构

中断处理过程是有CPU直接调用的,CPU有专门的寄存器IDTR来保存IDT在内存中的位置,本文写为IDTR.base。IDTR有48为,前32为是IDT在内存中的位置(线性地址),后16为是IDT的大小,本文写为IDT.limit。程序可以使用LIDT和SIDT指令来读写IDTR。

IDT是一个最大为256项的表,每个表项为8字节。称为中断门。CPU通过IDT.base+n*8来寻找门。

根据中断号对应的异常类型不同(Faults/Traps/Aborts)8个字节的意义也不同。

如上图所示IDT门中的最后两个byte是ISR在内存中的高16位,最开始前两个字节是ISR在内存中地址的低16位。

三、使用WinDbg观察、调试IDT

使用Vmware配置好内核调试环境[link]。

WinDbg有支持查看IDT的扩展命令!idt

!idt –a 命令可以看到所有中断处理函数的地址。
r idtr 参看idtr寄存器中保存的idt表地址。
idt每个表项有8bytes,两个dword大。

(注意.reload /i 加载符号文件)

kd> !idt -a

Dumping IDT:

00: 8053f19c nt!KiTrap00
01: 8053f314 nt!KiTrap01
02: Task Selector = 0x0058
03: 8053f6e4 nt!KiTrap03
04: 8053f864 nt!KiTrap04
05: 8053f9c0 nt!KiTrap05
06: 8053fb34 nt!KiTrap06
07: 8054019c nt!KiTrap07
08: Task Selector = 0x0050
09: 805405c0 nt!KiTrap09
0a: 805406e0 nt!KiTrap0A
0b: 80540820 nt!KiTrap0B
0c: 80540a7c nt!KiTrap0C
0d: 80540d60 nt!KiTrap0D
0e: 80541450 nt!KiTrap0E
… …

kd> r idtr
idtr=8003f400
kd> db idtr
8003f400  9c f1 08 00 00 8e 53 80-14 f3 08 00 00 8e 53 80  ......S.......S.
8003f410  3e 11 58 00 00 85 00 00-e4 f6 08 00 00 ee 53 80  >.X...........S.
8003f420  64 f8 08 00 00 ee 53 80-c0 f9 08 00 00 8e 53 80  d.....S.......S.
8003f430  34 fb 08 00 00 8e 53 80-9c 01 08 00 00 8e 54 80  4.....S.......T.
8003f440  98 11 50 00 00 85 00 00-c0 05 08 00 00 8e 54 80  ..P...........T.
8003f450  e0 06 08 00 00 8e 54 80-20 08 08 00 00 8e 54 80  ......T. .....T.
8003f460  7c 0a 08 00 00 8e 54 80-60 0d 08 00 00 8e 54 80  |.....T.`.....T.
8003f470  50 14 08 00 00 8e 54 80-80 17 08 00 00 8e 54 80  P.....T.......T.

可以看到,这个时候IDT的基地址是在803f400处。
注意观察其中3号中断门 e4 f6 08 00 00 ee 53 80 ISR 3 
int 3是trap门,按照之前说的ISR地址构造方法,得到8053f6e4的中断服务程序地址。

好,我们观察了IDT表(知道了IDT表的结构,自己写一个!idt WinDbg扩展也是很简单的事情),但是,使用windbg调试IDT表式不可能的。WinDbg的工作就要依赖于debuggee系统的中断向量,如果在ISR 3里写个int 3,那么BSOD是绝对的。Windbg和Debuggee系统是通过com口连接的,当Debuggee系统中产生了int3中断,系统首先进入到ISR 3中。在ISR 3中判断存在内核调试器,然后通过com口和WinDbg通行。这个处理过程本身就依赖于Debuggee系统的ISR。如果在ISR 3中又存在一个int 3那么就无限递归了。
 (待续)

IDT系列:(一)初探IDT,Interrupt Descriptor Table,中断描述符表的更多相关文章

  1. 中断描述符表(Interrupt Descriptor Table,IDT)

    中断描述符表(Interrupt Descriptor Table,IDT)将每个异常或中断向量分别与它们的处理过程联系起来.与GDT和LDT表类似,IDT也是由8字节长描述符组成的一个数组. #pr ...

  2. Linux中断技术、门描述符、IDT(中断描述符表)、异常控制技术总结归类

    相关学习资料 <深入理解计算机系统(原书第2版)>.pdf http://zh.wikipedia.org/zh/%E4%B8%AD%E6%96%B7 独辟蹊径品内核:Linux内核源代码 ...

  3. Bran的内核开发教程(bkerndev)-07 中断描述符表(IDT)

    中断描述符表(IDT)   中断描述符表(IDT)用于告诉处理器调用哪个中断服务程序(ISR)来处理异常或汇编中的"int"指令.每当设备完成请求并需要服务事, 中断请求也会调用I ...

  4. JS组件系列——表格组件神器:bootstrap table

    前言:之前一直在忙着各种什么效果,殊不知最基础的Bootstrap Table用法都没有涉及,罪过,罪过.今天补起来吧.上午博主由零开始自己从头到尾使用了一遍Bootstrap Table ,遇到不少 ...

  5. JS组件系列——表格组件神器:bootstrap table(二:父子表和行列调序)

    前言:上篇 JS组件系列——表格组件神器:bootstrap table 简单介绍了下Bootstrap Table的基础用法,没想到讨论还挺热烈的.有园友在评论中提到了父子表的用法,今天就结合Boo ...

  6. JS组件系列——表格组件神器:bootstrap table(三:终结篇,最后的干货福利)

    前言:前面介绍了两篇关于bootstrap table的基础用法,这章我们继续来看看它比较常用的一些功能,来个终结篇吧,毛爷爷告诉我们做事要有始有终~~bootstrap table这东西要想所有功能 ...

  7. 构建安全的Xml Web Service系列之初探使用Soap头

    原文:构建安全的Xml Web Service系列之初探使用Soap头 Xml Web Service 从诞生那天就说自己都么都么好,还津津乐道的说internet也会因此而进入一个新纪元,可5年多来 ...

  8. 9.1 翻译系列:数据注解特性之----Table【EF 6 Code-First 系列】

    原文地址:http://www.entityframeworktutorial.net/code-first/table-dataannotations-attribute-in-code-first ...

  9. [转]JS组件系列——表格组件神器:bootstrap table

    原文地址:https://www.cnblogs.com/landeanfen/p/4976838.html 前言:之前一直在忙着各种什么效果,殊不知最基础的Bootstrap Table用法都没有涉 ...

随机推荐

  1. 第10章:深入浅出Ansible

    1.Ansible介绍 1).Ansible的优点 Ansible是一个简单的自动化引擎,可完成配置管理.引用部署.服务编排以及其他各种IT需求 Ansible是Python开发并实现的开源软件,其依 ...

  2. S03_CH01_AXI_DMA_LOOP 环路测试

    S03_CH01_AXI_DMA_LOOP 环路测试 1.1概述 本课程是本季课程里面最简单,也是后面DMA课程的基础,读者务必认真先阅读和学习. 本课程的设计原理分析. 本课程是设计一个最基本的DM ...

  3. spring-boot-plus集成Shiro+JWT权限管理

    SpringBoot+Shiro+JWT权限管理 Shiro Apache Shiro是一个强大且易用的Java安全框架,执行身份验证.授权.密码和会话管理. 使用Shiro的易于理解的API,您可以 ...

  4. js摄像头

    <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8& ...

  5. 使用cublas 矩阵库函数实现矩阵相乘

    2014-08-10 cublas中执行矩阵乘法运算的函数 首先要注意的是cublas使用的是以列为主的存储方式,和c/c++中的以行为主的方式是不一样的.处理方法可参考下面的注释代码 // SOME ...

  6. JS笛卡尔积算法与多重数组笛卡尔积实现方法示例

    js 笛卡尔积算法的实现代码,据对象或者数组生成笛卡尔积,并介绍了一个javascript多重数组笛卡尔积的例子,以及java实现笛卡尔积的算法与实例代码. 一.javascript笛卡尔积算法代码 ...

  7. 用python 打印出爱心

    其实,如果程序员真的很浪漫,普通人不懂,科技兴旺,也许你是惊呆了!!!!! 今天,泰泰又给你带来了一个“程序员技术(浪漫)表现”教程.飞鲸水龙头有希望它能在这个七月前夜帮到你.如果使用成功,记得给泰泰 ...

  8. PAT Basic 1083 是否存在相等的差 (20 分)

    给定 N 张卡片,正面分别写上 1.2.…….N,然后全部翻面,洗牌,在背面分别写上 1.2.…….N.将每张牌的正反两面数字相减(大减小),得到 N 个非负差值,其中是否存在相等的差? 输入格式: ...

  9. Git---Ubuntu下的安装与使用

    Git---Ubuntu下的安装与使用 注意:学会Git的唯一方式是在实际使用中学习,切记不要尝试先记住一大堆理论知识或者Git命令.

  10. 2018 牛客网暑期ACM多校训练营(第一场) E Removal (DP)

    Removal 链接:https://ac.nowcoder.com/acm/contest/139/E来源:牛客网 题目描述 Bobo has a sequence of integers s1, ...