实模式下编程几个有意思的地方

实模式下编程几个有意思的地方,留个记录,备忘


1.千万别以为实模式下中断向量就一定在0000:0000的位置,其实这个地址是可以设置的,也就是说IDTR在实模式下同样影响中断向量表。

2.lgdt和lidt这两条指令如果在16位模式下执行,那么基地址仅低24位有效。切记。

3.关于实模式下的4G内存访问,进保护模式,给DS/ES/FS/GS中的一个或多个设置一个4G段,然后切回实模式,用这些段寄存器配合就可以访问4G内存了。
上面的很多人都知道,后面的很多人就不知道了。
我们假设用的FS存储的4G段,Base=0,Limit=4G

(1).为啥切换回实模式还能访问4G?
    切换实模式保护模式不会引起段属性的改变,段值并没有实际意义,仅仅在赋值的时候会影响段寄存器对应的一个属性寄存器。这也就是Intel要求模式改变后要紧跟一个长跳转的原因,很多资料上说是为了清指令队列或指令预取,其实都不是,主要是为了改变CS的段属性。

(2).切回实模式后对原来的4G段赋值会怎么样?
    很多人总是小心翼翼的呵护自己的4G段,总是担心对其赋值后就没法访问4G数据了。
    其实不用但是,经过研究发现,在实模式下对段寄存器进行赋值,改变的仅仅是其基地址而已。比如FS=1000h后,这时候Base变成10000h了,Limit还是4G,注意,这里如果要访问80000h的话就不能再用FS:[80000h]了,而应该用FS:[70000h],因为你的Base变了。很多人测试发现赋值后再访问的时候数据就错了,从而在今后的代码中小心翼翼去保护这个寄存器。所以,只要知道了原因,心里的负担就没这么重了。

(3).怎么恢复原来的4G段呢?
    前面说了,实模式下简单的对段赋值并不会改变段属性,只会改变的是基地址,所以如果你要恢复64K段的话需要再进一次保护模式,在保护模式下加载段值即可。

(4).为什么我的Hook访问4G段后会引起别的程序不正常?
    原因前面已经说了,就是4G段回实模式后还是4G段,不管怎么赋值,改变的仅仅是其基地址而已。一般来说不会影响别的程序的,因为4G段你要当作64K段来用也没什么问题的。但是如果有多个程序同时这样用的话就不好说了,一个设置为4G,一个设置为64K,到头来也不知道到底Limit是多少了,可能有人要说了,我把当时的状态保存出来不就可以了吗?呵呵。可能你忘记了一点,段的属性寄存器是无法访问的。


文章来自: 本站原创
引用通告: 查看所有引用 | 我要引用此文章
Tags:
相关日志:
评论: 0 | 引用: 0 | 查看次数: -
发表评论
昵 称:
密 码: 游客发言不需要密码.
内 容:
验证码: 验证码
选 项:
虽然发表评论不用注册,但是为了保护您的发言权,建议您注册帐号.