读书人

请大家帮小弟我看看把,已经弄了很久了

发布时间: 2012-02-14 19:19:19 作者: rapoo

请大家帮我看看把,已经弄了很久了,郁闷中.....!!
小弟正在DOS下学习TC,但有个几问题已经弄很久了都没有答案,麻烦大家帮我看看把!

问题一、在TC环境下物理地址和逻辑地址的问题
在DOS下的20位地址是物理地址,而该地址对应的逻辑地址应该为 16位段地址:16位偏移地址.在TC中:
int i = 123;
int *p = &i;
printf( "%x \n ", p );
输出的十六进制值,这个是物理地址吗?还是其他的什么地址?


问题二、如何取物理地址中的值(我的测试目标是中断向量,因为其是在固定的内存地址中的)
取相应中断向量所指向的函数入口地址:
做法一:
int main()
{
void ( **p ) = 0;
p = 0x00000 + 0x14 * 4; // 段地址*16 + 偏移地址 = 实际物理地址(中断向量地址)
printf( %x, *p ); // 实际14H的地址入口.
return 0;
}

做法二:
int main()
{
void ( *p )() = 0;
p = getvect( 0x14 );
printf( "%x\n ", p );
return 0;
}

做法三、
int main()
{
void ( **p ) () = 0;
p = MK_FP( 0x00, 0x50 );
printf( "%x\n ", *p );
return 0;
}

为什么方法一和三的结果是0,而方法二的结果却是“E739”呢?
而且按照中断向量地址应该 = 中断号 * 4(中断向量在DOS的0-3FFH的空间中所以段基地址为0)这样的算法算出来也应该是 0X50啊。
难道中断向量表中的元素的段基地址不为 0 吗?

请大家帮我看看把,小弟实在是不明白了!有劳大家了!


[解决办法]
int main()
{
void ( **p ) = 0;
p = 0x00000 + 0x14 * 4; // 段地址*16 + 偏移地址 = 实际物理地址(中断向量地址)
printf( %x, *p ); // 实际14H的地址入口.
return 0;
}
//这样得到的永远是虚拟地址,要得到物理地址,请参阅侯佩老大的blog,而且你需要预备一些其他知识
http://blog.csdn.net/mydo
[解决办法]
问题一、在TC环境下物理地址和逻辑地址的问题
在DOS下的20位地址是物理地址,而该地址对应的逻辑地址应该为 16位段地址:16位偏移地址.在TC中:
int i = 123;
int *p = &i;
printf( "%x \n ", p );
输出的十六进制值,这个是物理地址吗?还是其他的什么地址?


物理地址对你是不可见的, 只有操作系统可见~!
你见到的都是逻辑地址, 所以如果你不是搞特别底层的东西的话,忘掉物理地址这个概念


问题二
你取的还是逻辑地址, 也就是虚拟地址。。。
要读物理地址内容, 得靠操作系统。。。
[解决办法]
问题一、在TC环境下物理地址和逻辑地址的问题
20位地址最多可寻址1M的内存空间
而就算是在dos下内存的容量也不止1M,所以才有扩展内存技术.
而你得到的一般不会是物理地址,具体是什么东西怎么来的我也不知道.

问题二、如何取物理地址中的值(我的测试目标是中断向量,因为其是在固定的内存地址中的)
取相应中断向量所指向的函数入口地址:

做法一:
int main()
{
void ( **p ) = 0;
p = 0x00000 + 0x14 * 4;
printf( "%x ", *p );
return 0;
}
//这里应该改为printf( "%x ",p);因为p=0x50,
//假如用printf( "%x ", *p );得到的是p指向的内容
//也许你以为你用的是二级指针,*p还是地址,但它不是p,想想!


做法二:
int main()
{
void ( *p )() = 0;


p = getvect( 0x14 );
printf( "%x\n ", p );
return 0;
}
//如果中断向量的段基址是确定地等于0,那干什么要把它存起来,不是浪费空间吗?

做法三、
int main()
{
void ( **p ) () = 0;
p = MK_FP( 0x00, 0x50 );
printf( "%x\n ", *p );
return 0;
}
//这个和 做法一 本质上是一样的
//你需要把printf( "%x\n ", *p ); 改为printf( "%x\n ", p );



[解决办法]
老的DOS的实模式貌似能访问到物理地址。但后来的DOS和现在的windows下的DOS模拟机都是保护模式,不可能访问到物理地址,硬要访问的话会产生保护性错误。

你在TC下输出的指针的值是逻辑地址。

读书人网 >C语言

热点推荐