如果改变CS段寄存器会发生什么? (你会怎么做?)

问题描述 投票:0回答:2

我读了这篇文章:http://static.patater.com/gbaguy/day3pc.htm

它包括这句话

永远不要改变CS!!

但是,如果您修改了

CS
段寄存器,到底会发生什么? 为什么这么危险?

assembly x86 x86-16 memory-segmentation
2个回答
9
投票

cs
是代码段。
cs:ip
,即
cs
ip
(指令指针)一起指向下一条指令的位置。因此,对
cs
ip
或两者的任何更改都会更改获取和执行下一条指令的地址。

通常您可以将

cs
更改为
jmp
(跳远)、
call
(长叫)、
retf
int3
int
iret
。在 8088 和 8086 中,
pop cs
也可用(操作码 0x0F)。
pop cs
在 186+ 中不起作用,其中操作码 0x0F 是为多字节指令保留的。 http://en.wikipedia.org/wiki/X86_instruction_listings

跳远或长叫本身并没有什么危险。您只需要知道您跳转或调用的位置,并且在保护模式下您需要有足够的权限才能执行此操作。在 16 位实模式(例如 DOS)下,您可以跳转并调用您想要的任何地址,例如

jmp 0xF000:0xFFF0
cs
设置为
0xF000
,并将
ip
设置为
0xFFF0
,这是 BIOS 代码的起始地址,从而重新启动计算机。不同的内存地址有不同的代码,从而导致不同的结果,理论上一切可能发生(如果你跳到用于格式化硬盘的BIOS代码,具有有效的寄存器和/或堆栈值,那么硬盘将被格式化'按要求')。实际上,大多数地址的
jmp
call
可能很快就会导致无效操作码或其他一些异常(除以零、除溢出等)。


2
投票

在保护模式和长模式(即非16位实模式)下,设置包括CS在内的任何段寄存器不再只是将段基址设置为

Sreg<<4
;这只是在实数模式中作为 8086 获得额外 4 位线性地址的一种方式。 相反,sregs 索引到段描述符表 (GDT),具有基数 + 限制(正常基数 = 0 限制 = 4GiB,即平面内存模型),但也具有其他属性。

代码段描述符决定CPU模式(例如32位兼容模式与64位长模式)。 在 64 位内核上,64 位用户空间进程可以对某些 32 位代码生成

far jmp
。 这在实践中没有用,甚至可能在上下文切换后操作系统返回到您的进程时中断。

TODO:挖掘一个链接,其中有人展示了如何做到这一点。 我认为最近甚至有一个与此相关的问题,并提供了有关如何找到正确的段号的详细答案。

© www.soinside.com 2019 - 2024. All rights reserved.