鱼C论坛

 找回密码
 立即注册
查看: 3169|回复: 16

[已解决]32位保护模式下-代码段保护-有关EIP与段界限值关系式理解

[复制链接]
发表于 2017-11-20 16:16:29 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 兰陵月 于 2017-11-20 17:09 编辑

图片内容来自:
《x86汇编语言-从实模式到保护模式》
第12章 存储器的保护
12.4 地址变换时的保护
12.4.1 代码段执行时的保护

P213-P214(实体书的页码)
000.png
001.png
002.png


-------------------------------------------------------------------------------------------------------------------------------------------------------

003.png
请教上述内容中:
1、绿色下划线部分:“指令很有可能是跨越边界的,一部分在边界之内,
一部分在边界之外,或者一条单字节指令正好位于边界上”
(1)这句话是否意味着在一个段内,一条指令是可以跨界的?
比如这条指令“mov gs,eax”,32位保护模式下其机器码为“8EE8”。
假如它在内存中的存放如下图:
004.png
(2)如果(1)成立,那段描述符内的界限值还有何意义?
难道仅仅是用来限制EIP指针吗?
(3) 005.png
在讲述上图中的“存储器的段描述符格式”时,书中说:
006.png
如上图蓝框中红色下划线部分:“段界限决定了偏移量的最大值。”
再加上前面““指令很有可能是跨越边界的”的这句话,
是否能够说明段的长度并不是由段界限值决定的?
也就是说,在编程的时候,我们并不能确定段的实际大小?
(4)在段的实际大小不能知晓的情况下,如果紧临代码段的尾部定义数据段。
那就会发生不可预知的错误吧。
会不会发生紧临代码段的尾部定义数据段的情况?
2、红色下划线部分:“要执行的那条指令,其长度减 1 后,与 EIP 寄存器的值
相加,结果必须小于等于实际使用的段界限”,以及红色框内的表达式。
它们是如何得出来的?麻烦详细解释一下。



麻烦手把手一步一步介绍并解释一下,我卡住了~~~~
最佳答案
2017-11-20 18:52:22
本帖最后由 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  如果分开定义代码段检测代码的 数据段检测数据的,如果在代码里面定义则当做代码段检测段界限

本帖被以下淘专辑推荐:

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2017-11-20 18:52:22 | 显示全部楼层    本楼为最佳答案   
本帖最后由 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  如果分开定义代码段检测代码的 数据段检测数据的,如果在代码里面定义则当做代码段检测段界限
(VL1A6GSRPT[5`JT0$)P%]W.png

评分

参与人数 1荣誉 +5 鱼币 +5 贡献 +3 收起 理由
兰陵月 + 5 + 5 + 3 热爱鱼C^_^

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-11-20 19:00:29 | 显示全部楼层
本帖最后由 yizhi 于 2017-11-20 19:03 编辑

第一次回帖好激动
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-11-20 19:37:26 | 显示全部楼层
yizhi 发表于 2017-11-20 19:00
第一次回帖好激动


既然你第一次都给我了,那我给你一点分分和贡献吧,不多,哈哈

你的答案,我慢慢看~~~~
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-11-20 19:44: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点,没搞懂,所以这里还是搞不懂。

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-11-20 19:47:47 | 显示全部楼层
兰陵月 发表于 2017-11-20 19:44
1.假如段界限0x1FF 粒度为字节 而且现在EIP是0x1FF指向刚好是单字节指令NOP 因为它是段内最后一个允许的 ...

看那张图,很说明问题啦 细心看
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-11-20 19:58:44 | 显示全部楼层
yizhi 发表于 2017-11-20 19:47
看那张图,很说明问题啦 细心看

看了,没用,我思维已经陷入死胡同了。

我是思考一下午才发的帖子。

现在需要一个把我从思维死胡同里拉出来的人,

所以,恳请像教白痴的一样教我。。。。

比如说,讲解1+1=2这个题目,你就跟我说:“你看,这是我的第一个手指,这是我另外一个手指,那么放到一起是几个手指啊”,我就回答“是2个”。

恳请用上面这种方法教我。。。。。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-11-20 20:05:28 | 显示全部楼层
yizhi 发表于 2017-11-20 18:52
1.假如段界限0x1FF 粒度为字节 而且现在EIP是0x1FF指向刚好是单字节指令NOP 因为它是段内最后一个允许的访 ...

我原来的理解是

既然设置了段界限,说明了代码段不可能到边界的地方。就算是到边界的地方,那肯定也是一个有效指令结束处。也就是说EIP指向最后一个指令的开始处,这个指令的结束处才是边界。

书中来这么一出“指令很有可能是跨越边界的,......”这么一句话,我就彻底晕菜了。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-11-20 20:12:41 | 显示全部楼层
本帖最后由 兰陵月 于 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本来就指向该指令第一个位置。所以要减一。
其实就是简单的数学计算问题。
也就是说如果段边界处有指令,
则肯定最后一个字节结束的地方也是某个有效指令结束的地方。
否则会发生错误。

我这样理解是对的吧~
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-11-20 20:19:05 | 显示全部楼层
其实就是【2010年-2020年并不是10年而是11年】的道理一样,是吧

我竟然卡在这个上面。。。。。。。。。。。。。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-11-20 20:22:07 | 显示全部楼层
兰陵月 发表于 2017-11-20 20:12
已经明白了。

假设段边界处最后要一条要取的指令为当前要取的指令

对,不往我做啦这张图
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-11-20 20:28:11 | 显示全部楼层
第一次玩鱼C,什么都不懂 望关照
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2017-11-20 22:56:43 | 显示全部楼层
yizhi 发表于 2017-11-20 20:28
第一次玩鱼C,什么都不懂 望关照

都是从0开始的,互相学习吧。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-11-21 15:27:09 | 显示全部楼层
兰陵月 发表于 2017-11-20 22:56
都是从0开始的,互相学习吧。

嗯嗯在学WIN32API程序设计汇编
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-11-21 18:36:04 | 显示全部楼层
yizhi 发表于 2017-11-21 15:27
嗯嗯在学WIN32API程序设计汇编

我前面学过一段时间,因为很多基础概念没学懂,所以又回到基础汇编来了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-11-21 19:08:14 | 显示全部楼层
兰陵月 发表于 2017-11-21 18:36
我前面学过一段时间,因为很多基础概念没学懂,所以又回到基础汇编来了

我建议你直接学W32 因为后面根本用不到,或者说再W32基本用不到那些知识
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-11-21 19:49:38 | 显示全部楼层
不嫌弃我这个小白可以加我QQ1656637933
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-26 20:23

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表