少于 1 分钟阅读 次阅读

概要:介绍 %cs(代码段寄存器)与 %eip(指令指针寄存器)的字长、作用与工作机制,并说明 CS:EIP 组合如何定位下一条指令,以及段内跳转与跨段跳转的区别。

在 x86 体系结构中,%cs%eip 是两个极其关键的寄存器,它们像是一对“搭档”,共同决定了 CPU 接下来要执行哪一条指令。

1. %cs (Code Segment Register,代码段寄存器)

  • 字长:16 位。
  • 核心作用:它用来存放当前正在执行的代码段的基地址(在实模式下)或段选择子(在保护模式下)。
  • 通俗理解:在内存中,程序是被分段存放的(比如代码段、数据段、堆栈段等)。%cs 就像是一个路牌,专门指向存放“程序代码”的那块区域的开头。
  • 权限控制:在保护模式下,%cs 寄存器的最低两位(RPL,请求特权级)还决定了当前 CPU 的执行权限(比如是运行在内核态的 Ring 0,还是用户态的 Ring 3)。

2. %eip (Extended Instruction Pointer,扩展指令指针寄存器)

  • 字长:32 位。(在 16 位时代叫 %ip,在 64 位时代叫 %rip)。
  • 核心作用:它用来存放下一条将要执行的指令在代码段内的偏移量(Offset)。
  • 工作机制
  • 自动递增:CPU 每从内存中取走一条指令,%eip 的值就会自动增加,加上刚刚取走的那条指令的字节长度,从而指向紧接着的下一条指令。
  • 被动修改:你不能用普通的 mov 指令直接去修改 %eip(比如 mov %eax, %eip 是非法的)。它只能通过跳转指令(jmp)、函数调用指令(callret)或中断操作来间接改变。

它们是如何协同工作的?(CS:EIP 机制)

CPU 要知道下一条去哪取指令,永远依靠的是 CS:EIP 这个组合。

  • 定位物理地址:CPU 会把 %cs 提供的“段基址”和 %eip 提供的“段内偏移量”结合起来。
  • 实模式下:物理地址 = CS << 4 + EIP
  • 保护模式下:CPU 会通过 %cs 里的选择子去“全局描述符表 (GDT)”里查到代码段的基地址,再加上 %eip 里的偏移量,算出线性地址(最终映射到物理地址)。

  • 执行流程:只要改变了 CS:EIP 的值,CPU 的执行流就会发生跳转。
  • 如果是段内跳转(比如同一个函数内的 if-elsewhile 循环),%cs 保持不变,只改变 %eip
  • 如果是跨段跳转(比如不同特权级之间的切换,或者调用其他代码段的系统调用),则需要同时修改 %cs%eip(通常被称为 Far Jump 或 Far Call)。

总结来说,%cs 决定了你在哪一栋楼(代码段)里,%eip 决定了你要去这栋楼的哪个房间(具体指令偏移)。没有它们,CPU 就不知道下一步该干什么。

留下评论