汇编临时小结2

来源:互联网 发布:苹果某个app连不上网络 编辑:程序博客网 时间:2024/05/16 12:11

好多概念, 花了好长时间看懂, 过一段时间就忘得一干二净,等要用到时,又得从零开始看起, 实在是很浪费时间。

所以把自己刚刚看懂的东西小结一下, 以备后用。 观点不成熟, 看的时候小心点,别被误导了。

 

1. 实模式和保护模式段的差别。

实模式和保护模式下都使用16位的段寄存器存放段基址信息,如CS,SS,ES等。不同的是, 实模式下段寄存器中存放的就是段基址,使用时把段基址*16 加上16位的偏移量就得到20位的地址信息。而在保护模式下, 所有段定义在一张表中,也就是我们常说的GDT,每个表项以8个字节详细定义某个段的起始地址、界限、属性等内容,而段寄存器中存放的段值此时只是起到一个索引的作用, 它指向GDT中的某个表项, 这个索引也就是我们常说的段选择子。使用的时候根据索引取得32位的段基址和普通寄存器中32位的段偏移,两者共同组成了实际的物理地址。

 

2. jmp指令

有几种常见形式:

    A. jmp xx, 跳转至某个标号, 跳转目标地址在当前段内。 IP的计算方法是当前IP + (跳转标号偏移-当前标号偏移)

实模式下偏移和保护模式的偏移概念是不一样的, 但因为IP的计算方法使得在实模式和保护模式下都能成功跳转至目标标号。

    B. jmp xx:xx,跳转至某个段内某偏移, 前一个xx表示目标段, 后一个表示目标偏移。

 

3. $$ 表示当前节(section)开始的地址。

 

4. 描述符基本结构: 段基址(32位), 段界限(20位), 段属性。通过一个8字节的描述符,详细定义了一个段的相关信息。

 

5. 调用门结构: 指向目标段的GDT selector(16位),目标段偏移(32位),属性(里面包括param count, TYPE, DPL等)。这所有信息也是通过一个描述符来表示的, 并放在GDT中。

 

6. 特权级转移

通常代码里的跳转都是在段内进行的,但有时需要进行段间转移。 先假设当前段DPL为x。

不通过调用门,而直接通过jmp或者call跳转时, 有以下规则:

一致代码段: CPL>=x, 可以访问,且跳转后CPL不变。

非一致代码段, CPL=x,且RPL<=x

 

可以看到,直接跳转是非常有限的,要想自由跳转,还需要通过调用门。

通过调用门,访问规则如下(设调用门的DPL为DPL_G):

一致代码段: CPL<=DPL_G, RPL<=DPL_G, CPL>=x

非一致代码段: 通过call指令时: CPL<=DPL_G, RPL<=DPL_G, CPL>=x, 通过jmp指令时: CPL<=DPL_G, RPL<=DPL_G, CPL=x

通过调用门,可以很好的实现低特权级向高特权级跳转。

同时需要注意: 在通过调用门跳转时,需要通过TSS保留从0~2的SS和EIP

 

 

 

 

7. CPL,RPL,DPL

《自己动手写操作系统》第二版49页写得很清楚。 

 

8. 分页机制

一个内存地址的大小是32位, 低12位存放页内偏移(也即1页有4k大小), 中间10位指示该内存地址在哪一页(一个页目录有1024页),高10位指示处于那个页目录(总共有1024个页目录)。

 

 

PDE存放的是页目录表, 它最多有1024项, 每一项指向每个页目录的起始地址。

PTE存放的是页表,  它最多有1024*1024项, 每一项指向某个页的物理地址。

分页通过PDE-PTE两级映射。 Cr3存放页目录基地址。

 

9. 中断和异常

中断通常在程序执行时因为硬件而随机发生, 通常用来处理cpu外部的事件, 比如外围设备的请求。

异常则通常在cpu执行指令过程中检测到错误时发生,比如遇到零除的情况。

当它们发生时, 都需要跳转到相应的处理程序中做相应处理, 对于中断我们通过中断向量来表示。

在实模式中的中断向量具体是怎样? 这个待研究。

 

在保护模式中, 首先需建立硬件中断与向量号之间的对应关系, 如键盘中断对应IRQ0, 鼠标中断对应IRQ1等。 

 

中断向量通过IDT进行描述,和GDT类似, 它通过lidt命令加载IDT基址。 这个IDT可以理解为一个数组,其中的每个元素就叫做IDT描述符,描述符的基本结构是目标选择子, 目标偏移, 属性。 IDT[0]就表示IRQ0,IDT[1]表示IRQ1, 依此类推, 形成所谓的中断向量。

原创粉丝点击