posts - 297,  comments - 15,  trackbacks - 0
在我们的C/C++学习生涯中、在我们大脑的印象里,通常只有指针的概念,很少听说指针还有远、近、巨之分的,从没听说过什么近指针、远指针和巨指针。
可以,某年某月的某一天,你突然看到这样的语句:
char near *p; /*定义一个字符型“近”指针*/
char far *p; /*定义一个字符型“远”指针*/
char huge *p; /*定义一个字符型“巨”指针*/
实在不知道语句中的“near”、“far”、“huge”是从哪里冒出来的,是个什么概念!本文试图对此进行解答,解除许多人的困惑。
这一点首先要从8086处理器体系结构和汇编渊源讲起。大家知道,8086是一个16位处理器,它设定了四个段寄存器,专门用来保存段地址:CS(Code Segment):代码段寄存器;DS(Data Segment):数据段寄存器;SS(Stack Segment):堆栈段寄存器;ES(Extra Segment):附加段寄存器。8086采用段式访问,访问本段(64K范围内)的数据或指令时,不需要变更段地址(意味着段地址寄存器不需修改),而访问本段范围以外的数据或指令时,则需要变更段地址(意味着段地址寄存器需要修改)。
因此,在16位处理器环境下,如果访问本段内地址的值,用一个16位的指针(表示段内偏移)就可以访问到;而要访问本段以外地址的值,则需要用16位的段内偏移+16位的段地址,总共32位的指针。
这样,我们就知道了远、近指针的区别:
Ø 近指针是只能访问本段、只包含本段偏移的、位宽为16位的指针;
Ø 远指针是能访问非本段、包含段偏移和段地址的、位宽为32位的指针。
近指针只能对64k字节数据段内的地址进行存取,如:
char near *p;
p=(char near *)0xffff;
远指针是32位指针,它表示段地址:偏移地址,远指针可以进行跨段寻址,可以访问整个内存的地址。如定义远程指针p指向0x1000段的0x2号地址,即1000:0002,则可写作:
char far *p;
p=(char far *)0x10000002;
除了远指针和近指针外,还有一个巨指针的概念。
和远指针一样,巨指针也是32位的指针,指针也表示为16位段:16位偏移,也可以寻址任何地址。它和远指针的区别在于进行了规格化处理。远指针没有规格化,可能存在两个远指针实际指向同一个物理地址,但是它们的段地址和偏移地址不一样,如23B0:0004和23A1:00F4都指向同一个物理地址23604!巨指针通过特定的例程保证:每次操作完成后其偏移量均小于10h,即只有最低4位有数值,其余数值都被进位到段地址上去了,这样就可以避免Far指针在64K边界时出乎意料的回绕的行为。当然,一次操作必须小于64K。下面的函数可以将远指针转换为巨指针:
void normalize(void far ** p)
{
  *p=(void far *)(((long)*p&0xffff000f)+(((long)*p&0x0000fff00<<12));
}
从上面的函数中我们再一次看到了指针之指针的使用,这个函数要修改指针的值,因此必须传给它的指针的指针作为参数。
讲到这里,笔者要强调的是:近指针、远指针、巨指针是段寻址的16bit处理器的产物(如果处理器是16位的,但是不采用段寻址的话,也不存在近指针、远指针、巨指针的概念),当前普通PC所使用的32bit处理器(80386以上)一般运行在保护模式下的,指针都是32位的,可平滑地址,已经不分远、近指针了。但是在嵌入式系统领域下,8086的处理器仍然有比较广泛的市场,如AMD公司的AM186ED、AM186ER等处理器,开发这些系统的程序时,我们还是有必要弄清楚指针的寻址范围。
如果读者还想更透彻地理解本文讲解的内容,不妨再温习一下微机原理、8086汇编,并参考C/C++高级编程书籍的相关内容。
posted on 2008-07-23 16:27 chatler 阅读(121) 评论(0)  编辑 收藏 引用 所属分类: C++_BASIS

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理


<2009年12月>
293012345
6789101112
13141516171819
20212223242526
272829303112
3456789

常用链接

留言簿(10)

随笔分类(307)

随笔档案(297)

algorithm

Books_Free_Online

C++

database

Linux

Linux shell

linux socket

misce

  • cloudward
  • 感觉这个博客还是不错,虽然做的东西和我不大相关,觉得看看还是有好处的

network

OSS

  • Google Android
  • Android is a software stack for mobile devices that includes an operating system, middleware and key applications. This early look at the Android SDK provides the tools and APIs necessary to begin developing applications on the Android platform using the Java programming language.
  • os161 file list

overall

搜索

  •  

最新评论

阅读排行榜

评论排行榜