引用:
原帖由 duncan 于 2008-5-31 00:34 发表
按照linuxkernel.net上走进内核 第四讲 的说法, 保护模式下 linux基本没有使用Intel cpu的段机制, 也没有使用ldt,那么cs,ds,ss等寄存器的作用似乎很小, 好像它们的值对每个应用程序都应该是一样的定值. 是这样的吗?
“从2.2版开始,Linux让所有的进程(或叫任务)都使用相同的逻辑地址空间”,所以对于各应用程序来说,段寄存器的值应该都是一样的。
但对于像wine这样模拟面向段的,windows下程序的应用程序,需要用到LDT,段寄存器中的值就可能会变化。
当然这些都是对于应用程序来说的。内核态下,段寄存器的内容当然和用户态下的不同。
正如“第四讲”中所说,段寄存器的作用虽小,但却不可省略,因为操作系统是运行在硬件的基础上的。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
引用:
原帖由 duncan 于 2008-5-31 01:46 发表
我试着运行的几个程序, 用gdb常看段寄存器的值,cs,ds,ss的值确实是确定的, 如下:
cs 0x73 115
ss 0x7b 123
ds 0x7b 123
es 0x7b 123
但 ...
段寄存器中的值只是“段选择符”。段选择符在描述符表中选中一个“段描述符”。段描述符描述了一个段。
先来看段选择符的结构:
bit15~bit3: 16位索引值得高位部分,低位为0。
bit2: TI位,选择描述符表,为0时代表索引值从GDT(全局描述符表)中进行选择。
bit1~bit0: RPL
再来看上面段寄存器中的值:
cs: 0000000001110 0 11
ss: 0000000001111 0 11
ds,es同ss
首先,一般的应用程序都使用GDT,所以TI位都为0。
Linux系统在安排GDT时,将用户代码段的描述符安排在了第14项,将用户数据段的描述符安排在了第15项。
又Linux把堆栈段当作数据段来处理,所以cs的索引部分为0xe。ss,ds,es的索引部分为0xf。
最后的RPL域,因为是应用程序是在用户态下,所以RPL值都为3。
这些值和“第四讲”中给出的不一样,是因为新的Linux内核改变了GDT中各描述符位置的安排。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
以上是我的看法,不对之处还请大家指正~