32位保护模式下-代码段保护-有关EIP与段界限值关系式理解
本帖最后由 兰陵月 于 2017-11-20 17:09 编辑图片内容来自:
《x86汇编语言-从实模式到保护模式》
第12章 存储器的保护
12.4 地址变换时的保护
12.4.1 代码段执行时的保护
P213-P214(实体书的页码)
-------------------------------------------------------------------------------------------------------------------------------------------------------
请教上述内容中:
1、绿色下划线部分:“指令很有可能是跨越边界的,一部分在边界之内,
一部分在边界之外,或者一条单字节指令正好位于边界上”
(1)这句话是否意味着在一个段内,一条指令是可以跨界的?
比如这条指令“mov gs,eax”,32位保护模式下其机器码为“8EE8”。
假如它在内存中的存放如下图:
(2)如果(1)成立,那段描述符内的界限值还有何意义?
难道仅仅是用来限制EIP指针吗?
(3)
在讲述上图中的“存储器的段描述符格式”时,书中说:
如上图蓝框中红色下划线部分:“段界限决定了偏移量的最大值。”
再加上前面““指令很有可能是跨越边界的”的这句话,
是否能够说明段的长度并不是由段界限值决定的?
也就是说,在编程的时候,我们并不能确定段的实际大小?
(4)在段的实际大小不能知晓的情况下,如果紧临代码段的尾部定义数据段。
那就会发生不可预知的错误吧。
会不会发生紧临代码段的尾部定义数据段的情况?
2、红色下划线部分:“要执行的那条指令,其长度减 1 后,与 EIP 寄存器的值
相加,结果必须小于等于实际使用的段界限”,以及红色框内的表达式。
它们是如何得出来的?麻烦详细解释一下。
麻烦手把手一步一步介绍并解释一下,我卡住了~~~~{:5_104:} {:5_104:} 本帖最后由 yizhi 于 2017-11-20 19:02 编辑
1.假如段界限0x1FF 粒度为字节 而且现在EIP是0x1FF指向刚好是单字节指令NOP 因为它是段内最后一个允许的访问的偏移地址所以是可以访问的,所以EIP+指令长度-1 (0x1FF+1-1)满足<=实际使用界限,如果不这么做最后一个字节丢弃。
2.对于代码段来说限制访问一个不属于自己的段 对于数据段和栈段限制分别限制最大值和最小偏移量
3.不存在跨越边界,对于代码段是0<=(eip+指令长度-1)<=实际使用的界限 对于数据段是0<=(EA+操作数大小-1)<=实际使用的界限 对于栈段是 实际使用的界限+1<=(ESP+操作数长度)<=0xFFFFFFFF
4.段的大小是知道的 对于粒度是字节 段的长度=段界限+1 粒度是4KB 则段的长度=段界限*0x1000+0xfff+1如果分开定义代码段检测代码的 数据段检测数据的,如果在代码里面定义则当做代码段检测段界限 本帖最后由 yizhi 于 2017-11-20 19:03 编辑
第一次回帖好激动 yizhi 发表于 2017-11-20 19:00
第一次回帖好激动
既然你第一次都给我了,那我给你一点分分和贡献吧,不多,哈哈
你的答案,我慢慢看~~~~ yizhi 发表于 2017-11-20 18:52
1.假如段界限0x1FF 粒度为字节 而且现在EIP是0x1FF指向刚好是单字节指令NOP 因为它是段内最后一个允许的访 ...
1.假如段界限0x1FF 粒度为字节 而且现在EIP是0x1FF指向刚好是单字节指令NOP 因为它是段内最后一个允许的访问的偏移地址所以是可以访问的,所以EIP+指令长度-1 (0x1FF+1-1)满足<=实际使用界限,如果不这么做最后一个字节丢弃。
我就是“指令长度-1”的原理没搞懂,还请教诲。
2.对于代码段来说限制访问一个不属于自己的段 对于数据段和栈段限制分别限制最大值和最小偏移量
3.不存在跨越边界,对于代码段是0<=(eip+指令长度-1)<=实际使用的界限 对于数据段是0<=(EA+操作数大小-1)<=实际使用的界限 对于栈段是 实际使用的界限+1<=(ESP+操作数长度)<=0xFFFFFFFF
书中所说的“指令很有可能是跨越边界的”,就是绿色下划线部分,是什么意思,书不是说指令可能会跨越边界吗?指令又是属于段中的指令,指令跨界了,不就是段跨界了吗?难道说一个跨界的指令中?没跨的那部分有效,跨过去的那部分就无效了?就不属于这个段了?
4.段的大小是知道的 对于粒度是字节 段的长度=段界限+1 粒度是4KB 则段的长度=段界限*0x1000+0xfff+1如果分开定义代码段检测代码的 数据段检测数据的,如果在代码里面定义则当做代码段检测段界限
第3点,没搞懂,所以这里还是搞不懂。
兰陵月 发表于 2017-11-20 19:44
1.假如段界限0x1FF 粒度为字节 而且现在EIP是0x1FF指向刚好是单字节指令NOP 因为它是段内最后一个允许的 ...
看那张图,很说明问题啦 细心看 yizhi 发表于 2017-11-20 19:47
看那张图,很说明问题啦 细心看
看了,没用,我思维已经陷入死胡同了。
我是思考一下午才发的帖子。
现在需要一个把我从思维死胡同里拉出来的人,
所以,恳请像教白痴的一样教我。。。。
比如说,讲解1+1=2这个题目,你就跟我说:“你看,这是我的第一个手指,这是我另外一个手指,那么放到一起是几个手指啊”,我就回答“是2个”。
恳请用上面这种方法教我。。。。。{:5_104:} yizhi 发表于 2017-11-20 18:52
1.假如段界限0x1FF 粒度为字节 而且现在EIP是0x1FF指向刚好是单字节指令NOP 因为它是段内最后一个允许的访 ...
我原来的理解是
既然设置了段界限,说明了代码段不可能到边界的地方。就算是到边界的地方,那肯定也是一个有效指令结束处。也就是说EIP指向最后一个指令的开始处,这个指令的结束处才是边界。
书中来这么一出“指令很有可能是跨越边界的,......”这么一句话,我就彻底晕菜了。 本帖最后由 兰陵月 于 2017-11-20 20:15 编辑
yizhi 发表于 2017-11-20 19:47
看那张图,很说明问题啦 细心看
已经明白了。
假设段边界处最后要一条要取的指令为当前要取的指令
地址是0x00001111,指令的长度是2个字节。
那么该指令占据0x00001111、0x00001112两个单元。
此时EIP肯定指向0x00001111
EIP+指令长度-1=EIP+2-1=0x00001112.
实际上“EIP+指令长度-1”就是该指令最后一个字节的地址。
之所以要减一,是因为EIP本来就指向该指令第一个位置。所以要减一。
其实就是简单的数学计算问题。{:5_104:}
也就是说如果段边界处有指令,
则肯定最后一个字节结束的地方也是某个有效指令结束的地方。
否则会发生错误。
我这样理解是对的吧~ 其实就是【2010年-2020年并不是10年而是11年】的道理一样,是吧
我竟然卡在这个上面。。。。。。。。。。。。。 兰陵月 发表于 2017-11-20 20:12
已经明白了。
假设段边界处最后要一条要取的指令为当前要取的指令
对,不往我做啦这张图 第一次玩鱼C,什么都不懂 望关照 yizhi 发表于 2017-11-20 20:28
第一次玩鱼C,什么都不懂 望关照
都是从0开始的,互相学习吧。 兰陵月 发表于 2017-11-20 22:56
都是从0开始的,互相学习吧。
嗯嗯在学WIN32API程序设计汇编 yizhi 发表于 2017-11-21 15:27
嗯嗯在学WIN32API程序设计汇编
我前面学过一段时间,因为很多基础概念没学懂,所以又回到基础汇编来了 兰陵月 发表于 2017-11-21 18:36
我前面学过一段时间,因为很多基础概念没学懂,所以又回到基础汇编来了
我建议你直接学W32 因为后面根本用不到,或者说再W32基本用不到那些知识 不嫌弃我这个小白可以加我QQ1656637933
页:
[1]