Last updated on:February 18, 2023 pm

本文主要介绍了80x86的寄存器,80x86处理器的工作模式,Windows的内存管理和寻址方式。

1 80386的寄存器

1.1 通用寄存器

  • EAX: 通用寄存器。相对其他寄存器,在进行运算方面比较常用。在保护模式中,也可以作为内存偏移指针(此时,DS作为段寄存器或选择器)
  • EBX: 通用寄存器。通常作为内存偏移指针使用(相对于EAX、ECX、EDX)。在保护模式中,同样可以起这个作用。
  • ECX: 通用寄存器。通常用于特定指令的计数。在保护模式中,也可以作为内存偏移指针(此时,DS作为寄存器或段选择器)。
  • EDX: 通用寄存器。在某些运算中作为EAX的溢出寄存器(例如乘、除)。在保护模式中,也可以作为内存偏移指针(此时,DS作为段 寄存器或选择器)。

注:以上四个寄存器均为32位,且具有16-bit和8-bit的分组。即我们可以通过AX来访问EAX的低16位,通过AH和AL来访问AX的高8位和低8位。

  • ESI: 通常在内存操作指令中作为“源地址指针”使用。当然,ESI可以被装入任意的数值,但通常没有人把它当作通用寄存器来用。
  • EDI: 通常在内存操作指令中作为“目的地址指针”使用。当然,EDI也可以被装入任意的数值,但通常没有人把它当作通用寄存器来用。
  • EBP: 一个指针的寄存器。通常,它被高级语言编译器用以建造‘堆栈帧’来保存函数或过程的局部变量,不过,还是那句话,你可以在其中保存你希望的任何数据。SS是它的默认段寄存器或选择器。

注:以上三个寄存器也是32位寄存器,但是没有8-bit分组

1.2 段寄存器和选择器

  • CS: 代码段,或代码选择器。同IP寄存器一同指向当前正在执行的那个地址。处理器执行时从这个寄存器指向的段(实模式)或内存(保护模式)中获取指令。除了跳转或其他分支指令之外,你无法修改这个寄存器的内容。
  • DS: 数据段,或数据选择器。这个寄存器的低16 bit连同ESI一同指向的指令将要处理的内存。同时,所有的内存操作指令 默认情况下都用它指定操作段(实模式)或内存(作为选择器,在保护模式)。
  • ES: 附加段,或附加选择器。这个寄存器的低16 bit连同EDI一同指向的指令将要处理的内存。同样的,这个寄存器可以被装入任意数值,方法和DS类似。
  • **FS: **F段或F选择器(推测F可能是Free?)。可以用这个寄存器作为默认段寄存器或选择器的一个替代品。它可以被装入任何数值,方法和DS类似。
  • GS: G段或G选择器(G的意义和F一样,没有在Intel的文档中解释)。它和FS几乎完全一样。
  • SS: 堆栈段或堆栈选择器。这个寄存器的低16 bit连同ESP一同指向下一次堆栈操作(push和pop)所要使用的堆栈地址。这个寄存器也可以被装入任意数值,你可以通过入栈和出栈操作来给他赋值,不过由于堆栈对于很多操作有很重要的意义,因此,不正确的修改有可能造成对堆栈的破坏。

注:段寄存器和选择器在没有制定的情况下都是使用默认对应的寄存器。

1.3 特殊寄存器

  • EIP: 一个32位宽的寄存器 ,同CS一同指向即将执行的那条指令的地址。不能够直接修改这个寄存器的值,修改它的唯一方法是跳转或分支指令。(CS是默认的段或选择器)
  • ESP: 这个32位寄存器指向堆栈即将被操作的那个地址。尽管可以修改它的值,然而并不提倡这样做,因为如果你不是非常明白自己在做什么,那么你可能造成堆栈的破坏。对于绝大多数情况而言,这对程序是致命的。(SS是默认的段或选择器)

1.4 其他寄存器

以下寄存器均为32位

  • CR0, CR2, CR3: 控制寄存器。其中CR0的作用是切换实模式和保护模式
  • D0, D1, D2, D3, D6, D7: 调试寄存器。可以作为调试器的硬件支持来设置条件断点
  • TR3, TR4, TR5, TR6: 测试寄存器。用于某些条件测试

2 80x86的工作模式

80386处理器由三个工作模式:实模式,保护模式和虚拟86模式。实模式和虚拟86模式都是为了和8086处理器兼容而设置的。

2.1 实模式

  • 80386处理器被复位或加电的时候以实模式启动。这时候处理器中的各寄存器以实模式的初始化值工作。
  • 80386处理器在实模式下的存储器寻址方式和8086是一样的:由段寄存器的内容乘以16当作基地址,加上段内的偏移地址形成最终的物理地址。(32位地址线只用了20位,即1MB)
  • 实模式下80386处理器不能对内存进行分页管理,所以指令寻址的地址就是内存的实际地址
  • 实模式下,所有的段都是可读写和执行的。
  • 实模式下的80386不支持优先级,所有的指令相当于工作在特权级(优先级0),所以它可以执行所有的特权指令。实际上,80386就是通过在实模式下初始化控制寄存器,GDTR,LDTR, IDTR与TR等管理寄存器以及页表,然后再通过加载CR0使其中的保护模式使能位置位而进入保护模式的。
  • 实模式下中断处理方式和80386处理器相同。也是用中断向量表来定位中断服务程序地址。中断向量表的结构也和8086处理器一样:每4个字节组成一个中断向量,其中包括两个字节的段地址和2个字节的偏移地址。

2.2 保护模式

  • 当80386处理器工作在保护模式时,其所有功能都是可用的。
  • 80386所有的32根地址线都可提供寻址,物理寻址空间达4GB
  • 保护模式下,支持内存分页机制,提供了对虚拟内存的良好支持。
  • 保护模式下,支持多任务。仅依靠硬件即可再一条指令中实现任务切换。任务环境的保护工作是由处理器自动完成的。
  • 保护模式下,80386处理器还支持优先级机制。优先级分为4个(0级到3级),操作系统运行在最高优先级0级上。应用程序则运行在较低优先级上。配合良好的检查机制后,即可实现多任务的数据安全共享,也能够很好地隔离各个任务。
  • 实模式切换到保护模式是通过修改**控制寄存器CR0的控制位PE(位0)**实现的。在此之前,需要建立保护模式必须的数据表,如全局描述表GDT和中断描述表IDT等。
  • DOS操作系统运行于实模式下,而Windows操作系统运行于保护模式下。

2.3 虚拟86模式

  • 虚拟86模式是为了在保护模式下执行8086程序而设置的。(实模式的兼容做得并不足够)
  • 虚拟86模式是以任务形式在保护模式上执行的。在80386上可以同时支持由多个真正的80386任务和虚拟86模式构成的任务。
  • 虚拟86模式支持任务切换机制。在Windows操作系统中,有一部分程序专门用来管理虚拟86模式的任务,成为虚拟86管理程序
  • 虚拟86模式采用和8086一样的寻址方式:即用段寄存器乘以16当作基址在加上偏移地址。寻址空间为1MB
  • 虚拟86模式支持内存分页机制,因此能够很好地解决不同虚拟86任务的地址空间问题,通过分页机制的地址映射,让每个任务都认为自己在使用0~1MB的地址空间
  • 8086有部分指令在保护模式下属于特权指令,如屏蔽中断的cli和中断返回指令iret等。为了让8086的代码能够正常执行,虚拟86管理程序采用模拟的方式来完成这些指令:这些指令首先会引起保护异常,虚拟86程序则在异常处理程序中检查这些指令,并做出合理的响应。MS-DOS应用程序在Windows操作系统就是这样工作的。

3 Windwos的内存管理

3.1 DOS操作系统的内存安排

  • DOS运行于实模式,存储器的地址被安排在高端,从A0000h(即640KB)开始的384KB中。
  • 而在内存低端,则安排了中断向量表和BIOS数据区。
  • 剩余的从500h到A0000h总共不到640KB的内存是操作系统和应用程序所能使用的。**(著名的640KB限制)**
  • 当80386处理器(32位)推出后,可寻址空间达到了4GB,利用XMS驱动程序可以访问到所有的地址空间。但是16位的段寻址方式限制了DOS程序,“可见”的内存范围还是停留在前1MB范围内。所有高于1MB的扩展内存只能通过XMS驱动程序当作数据交换使用,程序执行的空间并无增加。

DOS的寻址方式:

  • 一个完整的地址分为段地址和偏移地址两部分组成:
    • 段地址xxxx存放在16位的段寄存器中
    • 16位的偏移地址yyyy存放在指令中
  • 计算方法:real = xxxx * 0x10 + yyyy

3.2 80386的内存寻址机制

实模式下的内存寻址方式:

保护模式下GDTR、LDTR、全局描述表、局部描述表和选择器的关系:

3.3 80386的分页机制

80386的内存地址转换:

虚拟内存的实现:

3.4 Windows的内存安排

4 参考

[1]《Windows PE 权威指南》


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!

x86汇编学习笔记(二) Previous
Invalid Driver Label in Windows Next

 TOC

载入天数... 载入时分秒...