免费注册 查看新帖 |

Chinaunix

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

head.s 汇编几个迷惑 [复制链接]

论坛徽章:
0
11 [报告]
发表于 2010-11-08 12:31 |只看该作者
回复 10# zylthinking


    没说这条跳转

我的意思是,在movl %eax,%cr0    这条指令执行时,因为pipeline的原因,有可能后面x条(x要看pipeline的深度)的操作数已经被取了,但是因为movl %eax,%cr0    还没完成,所以它们的操作数还在实模式下面取得的,自然是不对的(因为后面的指令都希望在保护模式下取数据和写数据).所以这条jmp是clear pipeline,保证后面的x条指令都在保护模式下从取指->解码->取操作数->执行的过程重做一遍

论坛徽章:
11
未羊
日期:2013-12-16 12:45:4615-16赛季CBA联赛之青岛
日期:2016-04-11 19:17:4715-16赛季CBA联赛之广夏
日期:2016-04-06 16:34:012015亚冠之卡尔希纳萨夫
日期:2015-11-10 10:04:522015亚冠之大阪钢巴
日期:2015-07-30 18:29:402015亚冠之城南
日期:2015-06-15 17:56:392015亚冠之卡尔希纳萨夫
日期:2015-05-15 15:19:272015亚冠之山东鲁能
日期:2015-05-14 12:38:13金牛座
日期:2014-12-04 15:34:06子鼠
日期:2014-10-16 13:40:4715-16赛季CBA联赛之八一
日期:2016-07-22 09:41:40
12 [报告]
发表于 2010-11-08 12:45 |只看该作者
回复  zylthinking


    没说这条跳转

我的意思是,在movl %eax,%cr0    这条指令执行时,因为pipeli ...
snail_314 发表于 2010-11-08 12:31


你说的是general 的情况, 看实际代码可以看到, movl $1f, %cr0 后若干指令为 jump 1f, movl $1f, %eax, jmp *%eax, 在开启保护模式后, eip 在 jmp *%eax 包括 执行  jmp *%eax时是没变的, 还是物理地址取指令; 而涉及到数据段的只有 movl $1f, %eax, 而这个如果 $1f 本身被编译后赋值应该本身就是虚拟地址, 那么即便之前是实模式下缓存的, 反正被缓存的$1f 是虚拟地址, 又有什么关系呢?

论坛徽章:
0
13 [报告]
发表于 2010-11-08 12:52 |只看该作者
回复 12# zylthinking


    恩.
并且我刚才说错了,上面代码只涉及了未分页和分页两种情况,和保护模式和实模式无关哈.纠正一下

论坛徽章:
0
14 [报告]
发表于 2010-11-08 13:24 |只看该作者
本帖最后由 snail_314 于 2010-11-08 13:46 编辑

回复 12# zylthinking


    我想到一个解释,不知说不说得通

jmp *%eax这条指令在未分页和分页的情况下执行上有区别

pipeline中都是放下面可能会执行的指令的.
未分页情况下cpu会从%eax求值出来的物理地址取指令放到pipeline中(肯定取出来的都是垃圾数据了,毕竟这时%eax大约是0xCxxxxxxx之类的数,这个物理地址下不知道会是些什么咚咚);
分页情况下cpu会从%eax求值出来的数经过mmu再到物理地址取指令放到pipeline中,这才是正确的下一条该执行的指令

依赖cpu的设计,如果pipeline设计得够深,加上什么prefetch等,那么第一种情况有可能会出现,应该是种隐患.
所以,第一条jmp是为了让第一种情况的隐患消失

论坛徽章:
11
未羊
日期:2013-12-16 12:45:4615-16赛季CBA联赛之青岛
日期:2016-04-11 19:17:4715-16赛季CBA联赛之广夏
日期:2016-04-06 16:34:012015亚冠之卡尔希纳萨夫
日期:2015-11-10 10:04:522015亚冠之大阪钢巴
日期:2015-07-30 18:29:402015亚冠之城南
日期:2015-06-15 17:56:392015亚冠之卡尔希纳萨夫
日期:2015-05-15 15:19:272015亚冠之山东鲁能
日期:2015-05-14 12:38:13金牛座
日期:2014-12-04 15:34:06子鼠
日期:2014-10-16 13:40:4715-16赛季CBA联赛之八一
日期:2016-07-22 09:41:40
15 [报告]
发表于 2010-11-08 13:38 |只看该作者
回复  zylthinking


    我想到一个解释,不知说不说得通

jmp *%eax这条指令在未分页和分页的情况下 ...
snail_314 发表于 2010-11-08 13:24


这个不能靠猜了, 只能找资料或者找高人指点了 呵呵

论坛徽章:
0
16 [报告]
发表于 2010-11-08 20:38 |只看该作者
jmp 1f                        /* flush the prefetch-queue */
这句是多余的。
有jmp *%eax 就够了。
实际中把jmp 1f去掉, 是没有问题的, 实践过。
以前在一个mailist看到过关于arm 也有类似讨论:
是开启mmu 后,因为流水线的关系,要用几个nop来填充。
后来有牛人现身,现代的cpu,已经完全解决了这个问题了,
开启mmu 后立即跳转是没有问题的。

论坛徽章:
0
17 [报告]
发表于 2010-11-08 21:43 |只看该作者
那以前的cpu为什么又不行?

论坛徽章:
2
2016猴年福章徽章
日期:2016-02-18 15:30:3415-16赛季CBA联赛之广夏
日期:2016-12-07 08:32:11
18 [报告]
发表于 2016-03-06 13:06 |只看该作者
本帖最后由 剑魂箫心 于 2016-03-06 18:56 编辑

回复 16# 奇门遁甲-lu


    回答很正确,我看了2.6.8的代码,这个地方已经改成了
  1. 192         movl %eax,%cr0          /* ..and set paging (PG) bit */
  2. 193         ljmp $__BOOT_CS,$1f     /* Clear prefetch and normalize %eip */
  3. 194 1:
  4. 195         /* Set up the stack pointer */
  5. 196         lss stack_start,%esp
复制代码
其中$__BOOT_CS是数字0x10,如果按照selector的格式来看,对应是GDT中index=2的descriptor。
内核编译链接后,标号1处的地址应该是3G+xx。为了方便我们假设它是0xc0100042
这样来说,L193就可以翻译成
  1. ljmp $0x10,$0xc0100042
复制代码
意思就是使用长跳转指令,直接把CS刷成0x10,把eip刷成0xc0100042,这样就完成了把寄存器中的物理地址全改为虚拟地址的过程。在这之后分页机制才会起作用。

总结一下,2.4内核中这个地方写的太罗嗦太晦涩,我做了下实验,将
  1.          jmp 1f /* flush the prefetch-queue */
  2. 1:
复制代码
直接删掉,编译后照样没问题。或者我们借鉴下2.6内核的做法,

  1.          movl %eax,%cr0 /* ..and set paging (PG) bit */
  2.          jmp 1f /* flush the prefetch-queue */
  3. 1:
  4.          movl $1f,%eax
  5.          jmp *%eax /* make sure eip is relocated */
  6. 1:
复制代码
直接改为
  1.          movl %eax,%cr0          /* ..and set paging (PG) bit */
  2.          ljmp $__KERNEL_CS,$1f
  3. 1:
  4.          /* Set up the stack pointer */
复制代码
这样就非常清晰了,我们也用长跳转把CS和EIP一块刷新,经测试,系统编译后可以正常启动。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP