免费注册 查看新帖 |

Chinaunix

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

请教:有关堆栈的问题 [复制链接]

论坛徽章:
0
11 [报告]
发表于 2009-07-13 01:36 |只看该作者
原帖由 mik 于 2009-6-16 22:57 发表


你真的想深入了解 x86 体系,好好的静下心来看看 amd/intel 官方的手册。

要想好好地学好每一条指令(如:call)要结合整个 x86 体系。


言归正题:

  编译器不知道 call 到底是不是 far,只有 ...



mik,

我参考了一下Intel的手册,再结合了一下目前所掌握的一些东西,整理如下:

   对于32位的CPU(X86 Intel),其线性地址空间为:0~4GB。假设在GDT里面设置了2个LDT,分别对应2个任务(任务A和任务B)。且GDT里各个段的大小总和少于4GB。在GDT的代码段进入任务A的代码段之前,我们要先加载LDTR,然后才能JMP/CALL进入任务A。同样,在任务A处如果要跳转到任务B,则在跳转前,也要将任务B的选择子等信息加载入LDTR,然后再跳转入任务B。之所以要重新加载LDTR,原因是发生了代码段间的跳转,同时也要进行特权级、类型、界限等的检测。因此跨段跳转其实是far call,应该要带上代码段地址的。
   但是当我查阅网上信息时,发现几乎所有资料都显示,我之前的问题的答案是call就行,不用far call。我尝试从另一个角度去考虑,是否应该是这样的:

   假设有2段代码C和D(分别对应上面例子中的任务A和任务B)

1、 当C和D是一起编译(即C和D是放在同一个文件中),并最终形成一个程序的情况下,当加载这个时,就好像从GDT->LDTA 或 LDTA->LDTB一样,因为在这个程序里面,只涉及到一个代码段,C和D都存在于这个代码段中(如果C和D的代码太多,超出了段界限,则会引起异常警告)。在同一个段中的call/jmp是不涉及到 远转移的。

2、 当C和D是分别编译,并最终连接成一个程序的情况下,与上1是一样的,因为在同一个代码段中,所以不是远转移。

3、 当C和D是分别编译成2个独立的程序,假设是E和F,则从程序E里 call/jmp 程序F,则属于远转移,这时就需要用到 far call。但一般这类情况很少,都是程序内的函数之间的转移的。


这是我最近的一些理解,不知道对不对?

[ 本帖最后由 sherf 于 2009-7-13 01:42 编辑 ]

论坛徽章:
0
12 [报告]
发表于 2009-07-13 19:15 |只看该作者

回复 #12 sherf 的帖子

........
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP