计算机内部是如何自动将段基址与偏移地址结合来计算物理地址的

在x86架构的实模式下,如何将段基址与偏移地址结合来计算物理地址,取决于正在执行的指令以及这些指令引用的寄存器。下面是一些常见情况:

默认段寄存器和偏移寄存器的使用:

  1. 代码段(CS):当执行跳转和调用指令时,默认使用CS寄存器作为基址。指令指针IP(或在某些指令中使用的偏移量)提供偏移地址。
  2. 数据段(DS):大多数数据相关的指令(如MOVADD等操作内存的指令)默认使用DS寄存器作为段基址。通用寄存器(如AXBXCXDXSIDI等)中的值通常用作偏移地址。
  3. 堆栈段(SS):与堆栈操作相关的指令(如PUSHPOPCALLRET等)默认使用SS寄存器作为段基址,而堆栈指针SP或基指针BP用作偏移地址。
  4. 附加段(ES):某些指令允许或要求使用ES作为额外的段寄存器,通常与字符串操作指令(如MOVSBMOVSW)结合使用。在这些操作中,ES用于目标地址的段基址,而DI通常用作目标的偏移地址。

显式指定段寄存器:

在某些指令中,可以显式指定使用哪个段寄存器,这是通过在指令中包含段寄存器的前缀来实现的。例如:

code
mov ax, ds:[bx] ; 使用DS作为段基址,BX作为偏移地址
mov ax, es:[di] ; 使用ES作为段基址,DI作为偏移地址

在保护模式下,段寄存器(CSDSESSSFSGS)的工作原理有所不同。它们存储的不再是段基址,而是指向段描述符的选择子(Selector)。这些选择子与全局描述符表(GDT)或局部描述符表(LDT)中的条目相关联,每个条目定义了段的基址、大小和访问权限。在这种模式下,段寄存器和偏移寄存器的组合仍然用于内存访问,但实际的物理地址计算涉及到段描述符中定义的段基址。