免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
123
最近访问板块 发新帖
楼主: ts0612
打印 上一主题 下一主题

关于TSS的问题 [复制链接]

论坛徽章:
0
21 [报告]
发表于 2009-06-11 12:18 |只看该作者
原帖由 ts0612 于 2009-6-11 02:33 发表



mik,

我大体上能明白你所说的,但有一点,“从 ring0 返回到 ring1 时,ring1 的 stack pointer(SS & esp)保存在 ring0 的 stack 中”这一步是谁做的?是系统自动完成的吗(类似于从 ring1->ring0  ...

既然要学习底层,一定要习惯看硬件手册。
你的问题都可以在Intel 《Intel(R) 64 and IA-32 Architectures
Software Developer¡¯s Manual
Volume 3A:
System Programming Guide, Part 1》4.8.5 “stack switching”一节找到答案。

下面这张图告诉你cpu怎么知道这些寄存器保存在栈上什么位置

stack.JPG (64.61 KB, 下载次数: 23)

stack.JPG

论坛徽章:
0
22 [报告]
发表于 2009-06-11 14:46 |只看该作者

回复 #21 zx_wing 的帖子

zx_wing,

.........

论坛徽章:
0
23 [报告]
发表于 2009-06-12 07:10 |只看该作者
原帖由 ts0612 于 2009-6-11 02:33 发表



mik,

我大体上能明白你所说的,但有一点,“从 ring0 返回到 ring1 时,ring1 的 stack pointer(SS & esp)保存在 ring0 的 stack 中”这一步是谁做的?是系统自动完成的吗(类似于从 ring1->ring0  ...




mik,

我大体上能明白你所说的,但有一点,“从 ring0 返回到 ring1 时,ring1 的 stack pointer(SS & esp)保存在 ring0 的 stack 中”这一步是谁做的?是系统自动完成的吗(类似于从 ring1->ring0 系统自动从TSS中取ss0:esp0)?如果是系统自动完成,那系统如何知道ss1:esp1到底放在ring0:stack里面的哪个单元?是不是说,在返回之前我要额外调整esp0,使它指向ring0:stack中的ss1:esp1?

这个问题还是没搞懂.....

论坛徽章:
2
2015亚冠之莱赫维亚
日期:2015-09-14 11:19:42操作系统版块每日发帖之星
日期:2015-11-05 06:20:00
24 [报告]
发表于 2009-06-12 10:20 |只看该作者
“从 ring0 返回到 ring1 时,ring1 的 stack pointer(SS & esp)保存在 ring0 的 stack 中”这一步是谁做的?
根据你的描述 应该是你自己做的 估计你超代码的时候没注意 就这么过去了
特权几改变就会发生栈切换。。。。楼上好几位牛人解释的很好了额

论坛徽章:
0
25 [报告]
发表于 2009-06-12 11:29 |只看该作者
你只管call和ret
堆栈切换,保存ss,esp,cs,ip这些都是cpu自动完成的。
cpu会自动把ring1的ss和esp保存在ring0栈里,ret返回的时候自动装回寄存器
中间还有很多复杂的权限检查等过程都由cpu自动完成

论坛徽章:
0
26 [报告]
发表于 2009-06-12 12:13 |只看该作者
原帖由 peimichael 于 2009-6-12 11:29 发表
你只管call和ret
堆栈切换,保存ss,esp,cs,ip这些都是cpu自动完成的。
cpu会自动把ring1的ss和esp保存在ring0栈里,ret返回的时候自动装回寄存器
中间还有很多复杂的权限检查等过程都由cpu自动完成



我之所以要弄清楚堆栈的情况,那是因为这实在是很重要。

回到主题,peimichael,你说的"cpu会自动把ring1的ss和esp保存在ring0栈里,ret返回的时候自动装回寄存器",我就很疑惑。举个例子,

假设:程序A(运行在ring0),程序dest(运行在ring2)。

1、程序A的代码如下(只是示意用的):
........
retf/ired dest
.......

2、将程序A的代码稍作改动,形成程序B的代码如下:
........
push x
push y
........
push z
........
retf/iretd dest
........
pop z
pop y
pop x

程序A和程序B的分别在于多了对 stack0的一些push/pop操作,显然在执行 retf/iretd dest 之前,程序B的堆栈内容已变了。假设程序A中所有的省略部分都不涉及 stack0 的操作,OK,你所说的cpu可以自动从stack0中找到ss1:esp1。但如果是程序B这种情况呢?在程序B的这种情况下cpu如何自动获知stack0中的ss1:esp1?

上面的只是一个例子,现实中应该还有更复杂的.......

[ 本帖最后由 ts0612 于 2009-6-12 12:14 编辑 ]

论坛徽章:
2
2015亚冠之莱赫维亚
日期:2015-09-14 11:19:42操作系统版块每日发帖之星
日期:2015-11-05 06:20:00
27 [报告]
发表于 2009-06-12 12:33 |只看该作者
........
push x
push y
........
push z
........
retf/iretd 这里手动保存了 ss esp eip cs eflags 软后切换任务 头一次任务的特殊地方

以后再有特权几切换会有CPU 帮你做上面的事

论坛徽章:
0
28 [报告]
发表于 2009-06-12 13:27 |只看该作者
原帖由 ts0612 于 2009-6-12 12:13 发表



我之所以要弄清楚堆栈的情况,那是因为这实在是很重要。

回到主题,peimichael,你说的"cpu会自动把ring1的ss和esp保存在ring0栈里,ret返回的时候自动装回寄存器",我就很疑惑。举个例子,

假设: ...

为什么不花点时间自己去看一看硬件手册呢?我都已经告诉你在哪一章可以找到答案了。
在论坛上等现成答案远不如自己花时间把问题弄懂来得深刻。
找到解决问题的方法和线索远比直接得到答案更有价值。

论坛徽章:
0
29 [报告]
发表于 2009-06-12 13:31 |只看该作者
用户在进行堆栈操作的时候必须保证对称,这样cpu才能找到正确的ss,esp等的值
像你程序b里面push了三个数之后在ret肯定会出错。
可以试试随便写一个c程序,在里面用嵌入汇编加入一条push指令不要pop,立马段错误。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP