前言
在先前的文章中提到了可以使用MOV、LES、LSS、LDS、LFS、LGS指令修改段寄存器
但CS段寄存器不能通过上面的指令修改;CS段寄存器为代码段寄存器,改变CS的同时必然要修改EIP
EIP寄存器
,用来存储CPU要读取指令的地址,CPU通过EIP寄存器
读取即将要执行的指令。每次CPU执行完相应的汇编指令之后,EIP寄存器
的值就会增加
代码跨段跳转
同时修改CS和EIP的指令
只改变EIP的指令
JMP FAR 指令
指令格式
JMP Selector:Offset
形如:JMP 0x20:0x00452610
- Selector为段选择子
- Offset为要跳转的偏移
CPU执行指令流程
以上面的 JMP 0x20:0x00452610为例,探究CPU的执行流程
执行流程为:
- 拆分段选择子
- 根据段选择子查表得到段描述符
- 权限检查
- 加载段描述符
- 代码执行
拆分段选择子
段选择子为:0x001B
将其转换成二进制得到:0000 0000 0001 1011
然后根据段选择子的结构得到:
根据段选择子查表得到段描述符
根据前面得到的段选择子的TI 可以确定要查询的表为GDT表
对应的段描述符地址 = GDT表首地址 + 索引× 段描述符长度 = GDT表首地址 + 索引 × 8
所以:对应的段描述符地址 = 0x8003f000 + 3×8= 0x8003f000 + 24 = 0x8003f000 + 0x18 = 0x8003f018
使用windbg
查看对应的段描述符地址