问题一:"在早期版本的Windows中,Microsoft不允许应用此程序访问2GB以上的地址空间.因此,有些有创意的开发人员决定对此加以利用.他们将指针的最高为作为一个标志位使用,只有他们的应用程序才知道该如何解释该标志位.当应用程序访问内存地址时,会在访问内存地址之前清除指针的最高位.可以想象,当此类应用程序在用户模式分区大于2GB的环境下运行时,"显然会死的很难看""
请问"他们将指针的最高为作为一个标志位使用,只有他们的应用程序才知道该如何解释该标志位.当应用程序访问内存地址时,会在访问内存地址之前清除指针的最高位" 这样做的目的是什么?
问题二:"在Windows中,所有.exe和动态链接库(dynamic-link library,通常简称DLL)都载入到这一区域(指用户模式分区).每个进程都有可能将这些DLL载入到这一分区内的不同地址(虽然这种可能性很小)." 请问这里又该如何理解?
请问"他们将指针的最高为作为一个标志位使用,只有他们的应用程序才知道该如何解释该标志位.当应用程序访问内存地址时,会在访问内存地址之前清除指针的最高位" 这样做的目的是什么?
问题二:"在Windows中,所有.exe和动态链接库(dynamic-link library,通常简称DLL)都载入到这一区域(指用户模式分区).每个进程都有可能将这些DLL载入到这一分区内的不同地址(虽然这种可能性很小)." 请问这里又该如何理解?
解决方案 »
- vc++ 2008 sp1中将集成TR1和MFC的新控件
- 在一个View里面, 图相放大到超出男家界后自动出现滚动条, 怎么实现?
- 菜鸟问题!!!!!!!!!
- 这样的错误是什么意思啊????
- 关于日期时间控件问题
- bitblt使用问题
- win32 Release 和win32 debug 是什么意思。我是新手,谢谢大家关注!
- 关于ftp:我想得到CInternetSession的状态,比如用户名错误了的消息!可是...
- 想与大家讨论问题QQ:40255392
- 一道问题,很急???
- MFC资源当中的Version信息中,语言是"中文"还是"英语"的这个属性有什么用么?
- fopen比CreateFile更强大?
0x00100000-0x7FFFFFFF
这样,32位机器上,用户程序的合法指针的最高位0x8000000总是0. 有些程序员就考虑利用这一位,记录一个bool信息。比如,
void print_msg(void *msg)
{
if(((unsigned long)msg)&0x80000000)
{
printf("int value: %d\n", *(int)(msg & ~0x80000000));
}
else
{
printf("string value: %s\n", msg);
}
}int main() {
{
int a = 10;
char *b = "hello";
print_msg( a | 0x8000000);
print_msg( b );
return 0;
}实际上这种做法是非常不好的,尤其是现在从win32向win64迁移的时候,这样的代码是完全不可移植的。2、程序都是载入内存执行的。比如生成一个hello.exe,有64K大小。系统新建一个进程,这个进程可以认为自身拥0x00000000-0xFFFFFFFF的4G地址,把整个hello.exe加载到内存的0x00400000开始的地址,可能才占用0x00400000-0x00410000的地址,还有大量地址可以使用。如果程序中引用了user32.dll,则系统可能把user32.dll加载到0x75000000-0x75400000的地址空间,那么从进程角度看,加入进来的内容,就是进程本身的一部分,并不区分这些内存是从磁盘文件hello.exe里面加载的,还是从磁盘文件user32.dll加载的。实际上,MS编译器编译dll时候建议的地址都是0x10000000,如果生成了两个动态链接库a.dll, b.dll,并且都由hello.exe引用,假设系统已经将a.dll加载到0x10000000开始的地址,那么在加载b.dll的时候,本应该加载到0x10000000开始的地址的,但此地址已经被a.dll占用了,应该使用其它地址(在PE加载里面使用reloc信息来处理)。