一个不太简单的问题,高手留步~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~`

yxwsbobo 2010-07-17 12:42:13
也是遗留下来的问题,今天想解决掉

void MyPorc()
{
printf("ok\n");
}

int main()
{
int Address = (int)&MyProc;
getchar();//此处下断点
return 0;
}

F5调试,运行到断点处,观察发现

MyProc 的值是 0x00fd13a0
Address的值是 0x00fd1023

查看内存 0x00fd1023 此处的代码是

MyProc:
00FD1023 E9 78 03 00 00 jmp MyProc (0FD13A0h)
@ILT+35(_WideCharToMultiByte@32):
00FD1028 E9 49 25 00 00 jmp WideCharToMultiByte (0FD3576h)
@ILT+40(@_RTC_AllocaHelper@12):
00FD102D E9 FE 05 00 00 jmp _RTC_AllocaHelper (0FD1630h)
_RTC_GetErrorFuncW:
00FD1032 E9 69 16 00 00 jmp _RTC_GetErrorFuncW (0FD26A0h)
@ILT+50(__RTC_NumErrors):
00FD1037 E9 94 15 00 00 jmp _RTC_NumErrors (0FD25D0h)


此处似乎是一张表?我想知道这是什么表,怎么来的 为什么获得MyProc 的地址却获得了这个地址的跳转地址
...全文
218 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
许文君 2010-07-17
  • 打赏
  • 举报
回复
学习了
jjfwenwenti 2010-07-17
  • 打赏
  • 举报
回复
xue_xi
jameshooo 2010-07-17
  • 打赏
  • 举报
回复
学习了
schlafenhamster 2010-07-17
  • 打赏
  • 举报
回复
#10楼的说法正确
sunlin7 2010-07-17
  • 打赏
  • 举报
回复
这个表是为了支持"Program Database for Edit and continue"和"link incremetally"而设的,在下次链接的时候,直接更新这个表就可以了。如果将函数声明为
static void MyPorc(){}
则这个函数就不会有写在这个表里面。

取消上面提到的那两项就不会再生成这个跳转表了。
adamwyb 2010-07-17
  • 打赏
  • 举报
回复
[Quote=引用楼主 yxwsbobo 的回复:]
int Address = (int)&MyProc;
[/Quote]

楼主这句是取了指向MyProc的指针,不是MyProc的地址,函数名就已经代表函数的地址了,所以如果改成:

int Address = (int)MyProc;

那么Address与MyProc的值应该是一样的了。

那个表是内存中的地址表,你Address的值是00FD1023,是指向MyProc,不是MyProc的值,当然就是跳转啦。
汪宁宇 2010-07-17
  • 打赏
  • 举报
回复
个人理解为函数的符号表,debug版本下编译器生成的辅助代码

假如你改成static void MyProc,那么这两个值是一样的!

webipstin 2010-07-17
  • 打赏
  • 举报
回复
这个表是为了跳入导入表用的,因为你的EXE启动后会固定装载到0x00400000的基地址空间,附带的dll会连到自己的基址空间,例如0x10000000,但如果此时此地址已经被其他dll文件加载后占用了,那么系统会给你分配一个其他空间地址加载你的dll,这张表的jmp就是跳向这个地址dll的相关函数,有可用是不用修正的地址,有可能是修正后的地址。
  • 打赏
  • 举报
回复
debug版 喜欢搞这个。
wocow3 2010-07-17
  • 打赏
  • 举报
回复
MyPorc是在dll中的函数?

MyProc:
00FD1023 E9 78 03 00 00 jmp MyProc (0FD13A0h)
@ILT+35(_WideCharToMultiByte@32):
00FD1028 E9 49 25 00 00 jmp WideCharToMultiByte (0FD3576h)
@ILT+40(@_RTC_AllocaHelper@12):
00FD102D E9 FE 05 00 00 jmp _RTC_AllocaHelper (0FD1630h)
_RTC_GetErrorFuncW:
00FD1032 E9 69 16 00 00 jmp _RTC_GetErrorFuncW (0FD26A0h)
@ILT+50(__RTC_NumErrors):
00FD1037 E9 94 15 00 00 jmp _RTC_NumErrors (0FD25D0h)
看起来应该是exe的导入表
gengzhen_2005 2010-07-17
  • 打赏
  • 举报
回复
这个表保存在系统专门分配的一个内存空间,无论何时我们都可以从这个表读取到相应函数的地址,函数的地址可能变化,但这个表的地址不变,也就是如果函数的地址变了,那么这个表会被相应的更新,但表的地址没变,所以虽然函数的地址变了,我们依然可以从表里面知道函数的地址。这是我的理解!!欢迎大家讨论一下。
Abcix 2010-07-17
  • 打赏
  • 举报
回复
int Address = (int)MyProc;

这样试试,你不就是想得到MyProc的地址吗?
jameshooo 2010-07-17
  • 打赏
  • 举报
回复
或者再加一句: int Address2 = (int)MyProc; 不要取指符,看看有没有不同。
jameshooo 2010-07-17
  • 打赏
  • 举报
回复
这张表不是我干的,是编译器干的,至于为什么要生成这张表,我没有深究过,也不知道原因,可能是为了方便编译器内部链接使用,也可能是为了保护代码区,针对所有函数的取指操作都缓存到这张表,降低代码区被破坏的可能性。

16,473

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧