汇编网首页登录博客注册
fishboy的学习博客
博客首页博客互动【做检测题】论坛求助

我的博客

个人首页 |  我的文章 |  我的相册 |  我的好友 |  最新访客 |  文章收藏 |  论坛提问 |  友情链接 |  给我留言  
图片载入中
学习动态

[2007-11-28 15:36] 【请教】C中如何查看长指针的段地址?

在C语言中,我们定义一个个长指针 Type far * ptr ,当我们printf(“%x”,ptr)的时候,打印出来的只是ptr的偏移地址,怎么才能查看到常指针的段地址呢?请兄弟们不吝指教一哈!
如:
main(){
char far * ptr;     /*定义一个长指针*/
ptr = (char far *)0x12345678;
printf("%x",ptr);/*打印指针*/
}
=================
看完留言后增加的内容
=================
main(){
 char * p;   /*短指针*/
 char far * ptr; /*长指针*/
 char huge * hp; /*巨指针*/
 p ="abcd";
 ptr = (char far *)0x1000ffff;
 hp = (char huge *)ptr; 
 printf("%lx \n",ptr);
 printf("%x:%x \n",p);
 /*发现都是32位的*/
 ptr++;
 printf("%lx \n",ptr);
 hp++;
 printf("%lx \n",hp);
 /*长指针和巨指针自增后的不同结果*/
 getch();
}
然后,百度了一下:
FAR   HUGE   指针是针对DOS平台的,为了跨越段的限制。在DOS下的指针默认是   near指针长度是   2字节   默认的段是数据段不能改变,   而如果我们要取得一个视频ROM中的数据时就需要   far指针   far指针长度是   4字节   2个字节指示段地址   2个字节指示偏移量或者huge指针   huge指针和far指针的最大不同是far指针在参加++运算时不会改变段地址,   
 如: p= 0x0080:0xffff;   ++p的结果是  0x0080:0x0000     
 而huge指针的话则是   0x1080:0x0000   
 还有就是比较运算时huge指针会先做规格化再比较,而far指针不会,这样有可能导致两个相同地址的指针由于地址覆盖的原因导致   比较时不同. 而huge指针由于先规格化所以不会.     
  在WINDOWS下由于内存模式是平坦的.   指针都是4字节的,在4G的空间中可以任意指向.   所以没有特别意义.
评论次数(22)  |  浏览次数(2352)  |  类型(MY PUZZLE) |  收藏此文  | 

[  游客   发表于  2007-12-02 17:38  ]

可以用_asm 嵌入汇编把CS的值找出来,不过这就不是C语言的方法了~~~

[  dave   发表于  2007-12-02 18:12  ]

远指针不是让编译程序把程序数据段地址作为指针的段地址部分, 
而是把指针的段地址与指针的偏移量直接存放在指针内。因此,远指针是由4 个字节构成。它可以指向内存中的任一目标,可以用于任一编译模式

[  cxn   发表于  2007-12-04 17:54  ]

这个简单 呵呵
printf("%x:%x",ptr);偏移地址:段地址

[  fishboy   发表于  2007-12-05 12:43  ]

to dave:
无论是怎么存放的,存放在哪,都必然应该有段地址的,既然偏移地址能打印出来,段地址必然也能找出来。
这才是我想问的。呵呵呵
to cxn:
原来如此啊!没想还有这样的使用,一个变量能用两个输出类型来用。

[  游客   发表于  2007-12-05 12:49  ]

re to:fishboy
不系吧,平坦模式没有段地址和偏移啊,要说有的话,段地址就是00000000H,偏移就是它的实际地址~~

[  dave   发表于  2007-12-05 13:18  ]

找到了,FAR指针是32位的高16位是段地址存储在DX寄存器中的~~~低16位是偏移两存储在AX中的。
原理是这样,但怎么显示出来呢,用LX格式符就OK了~嘿嘿
#include<stdio.h>
#include<stdlib.h>
int main()

    int far * ptr;     /*定义一个长指针*/
    ptr = (int far *)0x12345678;
    printf("%lx",ptr);/*打印指针*/
    system("pause");
    return 0;
}

[  dave   发表于  2007-12-05 14:16  ]

far指针有个局限例如当ptr=1000:FFFF的时候AX=FFFF
DX=1000
PTR++后就相当于INC AX了结果就成了1000:0000,而不是2000:0000
这时候需要用huge指针,它是一个按照32位运算的,所以是存储在内存中的,这种指针1000:FFFF 自增后是2000:0000,避免了far指针的问题,但是他的运算模式却决定了它的效率很低的

[  dave   发表于  2007-12-06 12:25  ]

PS:只有在far指针返回的时候是段放在DX,偏移放在AX,平时内存存放的时候高位内存放高位值,低位内存放低位值,楼主可以用TC+TD(turbo c &turbo debug)来验证下

[  fishboy   发表于  2007-12-07 12:18  ]

dave提到的ptr++的处理,应该就是有没有进行按位加的问题吧。可能当定义成了巨指针,在进行自增操作的时候就会进行按位加了吧。
多谢dave老兄了。

[  wdm   发表于  2007-12-07 14:10  ]

对,dos下是16位机环境,所以出现了长、短指针的概念。而windows的保护模式下都是32位的,指针都是32位,好像不是按段寻址的原理了,所以,长、短的指针好像在这里就没有定义时的重大意义了。
呵呵

[  wdm   发表于  2007-12-07 14:13  ]

对了,博主转的【汇编剖析指针】这个文章挺不错,楼上楼下的可以看看,体会一下汇编语言知识的伟大内涵。
本人真是为自己曾经学习过一点汇编知识而庆幸啊。

[  游客   发表于  2007-12-07 18:11  ]

恩。C中的指针是有点让人头晕。。继续研究中....

[  游客   发表于  2007-12-13 15:08  ]

原来,指针还有长的短的,甚至还有巨指针,这是巨强啊!我的“巨”续学习撒...

[  游客   发表于  2007-12-13 17:57  ]

路过,还没有学习C语言呢。有点天书!

[  游客   发表于  2007-12-13 17:58  ]

楼上先把汇编搞一搞吧。磨刀不误砍柴工。

[  wdm   发表于  2007-12-13 18:01  ]

恩,我们还是从汇编做起,才能打好根基,在编程之路上才走的更远..更远..远.......

[  游客   发表于  2007-12-13 18:09  ]

我顶啊!

[  Wednesday   发表于  2007-12-18 19:45  ]

很学习

[  cxn   发表于  2007-12-31 21:59  ]

更新了学习一下

[  游客   发表于  2008-01-07 17:11  ]

终于对c语言这个指针问题有了明晰的了解了,谢谢楼主

[  zkkpkk   发表于  2008-01-18 20:59  ]

汇编和C必学

 
 请输入验证码  (提示:点击验证码输入框,以获取验证码