函数的地址都是保存在哪里?

motiandalou 2011-06-25 02:30:00
调用函数时,程序怎么知道应该跳转到函数的定义处,函数的地址都是保存在哪里?是寄存器区、程序代码区还是栈中。
...全文
3286 32 打赏 收藏 转发到动态 举报
写回复
用AI写文章
32 条回复
切换为时间正序
请发表友善的回复…
发表回复
袁保康 2012-12-25
  • 打赏
  • 举报
回复
函数的地址对应程序的哪段?我来学习学习!
motiandalou 2011-07-13
  • 打赏
  • 举报
回复
继续追问,不弄清楚不罢休。
山书生 2011-06-30
  • 打赏
  • 举报
回复
学习@
pengzhixi 2011-06-29
  • 打赏
  • 举报
回复
保存在代码段,一般是通过相对地址调用,就是说一般是call 相对地址。
真正到了计算实际地址的时候就是相对地址加上call指令后一条指针的地址。就得到了要调用的函数地址。
赵4老师 2011-06-29
  • 打赏
  • 举报
回复
VC调试时按Alt+8,TC或BC用TD调试,打开汇编窗口看每句C对应的汇编并单步执行一遍不就啥都明白了吗。
(Linux或Unix下应该也可以在用GDB调试时,看每句C对应的汇编并单步执行。)
motiandalou 2011-06-29
  • 打赏
  • 举报
回复
来看看吧
小曦子 2011-06-28
  • 打赏
  • 举报
回复
看PE结构,里面有函数的导入表和导出表
wjb_yd 2011-06-27
  • 打赏
  • 举报
回复
函数地址是不需要保存的,如果你的程序没有用到任何动态链接库的话,所有函数的地址都是编译时指定好的。
motiandalou 2011-06-27
  • 打赏
  • 举报
回复 1
写错了,参数是自右向左入栈,也就是右边的参数首先入栈,
motiandalou 2011-06-27
  • 打赏
  • 举报
回复
某书上说,编译代码时会将函数的地址存放到一个符号表中,该符号表保存到一个文件中,符号表中保存了函数名,函数参数、参数类型和参数个数以及返回值的类型,当调用函数时,首先取执行函数的下个指令的地址,将其保存到栈中,然后读取符号表,从中查找函数名所对应的地址,也就是标号,找到标号后,用指令指针来保存,同样还要找函数的返回值类型,根据函数的返回值类型在栈中开辟空间,这样栈中就有了2个数据,一个是执行函数的下个指令的地址,一个返回值,当然现在还没有确定返回值是多少,只是分配了足够的空间,接着再从符号表中读取函数的参数类型和参数个数,在栈中再开辟一块空间,用来保存传递给函数的参数,参数是自左向右入栈,也就是左边的参数首先入栈,最后是在函数中定义的局部变量,当函数执行结束,并准备返回时,局部变量首先弹出栈,然后是参数,接着是返回值,最后是下个指令的地址,这样程序才会返回到调用函数的下个指令处执行,然后将返回值返回到下个指令处,我的问题是,假如是下个指令是return 0;那么返回值是不是要被return返回?
robert_chao 2011-06-26
  • 打赏
  • 举报
回复
函数地址应该是存在栈里
动感超哥 2011-06-26
  • 打赏
  • 举报
回复
这个 好像有个啥指针集、、、可以找到函数的定义、、、不懂 、、
T0Ols 2011-06-26
  • 打赏
  • 举报
回复
保存在代码区里, 函数定义一块 实现一块 调用的时候又一块 就是一顿 jmp call 在jmp
你脱壳就知道了
玩笑 2011-06-26
  • 打赏
  • 举报
回复
保存在哪?保存在哪?内存中?寄存器中????呵呵,
我还是那句话,楼主的问题让人感觉很奇怪,,,"函数地址",,,这东西在编译时就已经确定下来的东西,保存它干嘛?如果非问它保存在哪了,函数的"逻辑"地址保存在程序代码中了(其实就是代码的一部分),,,然后运行到相应地方时,再由系统去计算得出函数的具体位置 ,然后再去调用

怎么想这东西也涉及不到"保存"问题呀,编译时就确定的东西,哪来的"保存在哪"的问题,,这就好比去问#define MAX 1000 这个MAX保存在哪了????保存在哪了????,反正除了说保存在目标程序代码中了,我是想不出别的地方了
vcf_reader 2011-06-26
  • 打赏
  • 举报
回复
CODE PAGE
小江啊 2011-06-26
  • 打赏
  • 举报
回复
一堆牛人 汇编 寄存器。。。 新手表示压力很大
编译的时候代码全被放到代码区?
test()调用在编译的时候被转换成test定义在代码区的首地址?
ccnyou 2011-06-26
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 long2015 的回复:]

不是函数地址保存哪,而是整个函数实现保存在了一个地方。
编译时,主函数里对于函数的调用 如: add(2,3); 编译时就变成了add函数实现那个地址。
当执行到函数时,直接跳转到那个地址,执行完在跳转回来,接着执行add下面的。
[/Quote]

+1
5t4rk 2011-06-25
  • 打赏
  • 举报
回复
有一句话说不清楚地
楼主 ,举个例子吧
先写个小程序:
void fun(void)
{
printf("hello world");
}
void main(void)
{
fun()
printf("函数调用结束");
}
这是一个再简单不过的函数调用的例子了。
当程序进行函数调用的时候,我们经常说的是先将函数压栈,
当函数调用结束后,再出栈。这一切的工作都是系统帮我们自动完成的。
但在完成的过程中,系统会用到下面三种寄存器:
1.EIP
2.ESP
3.EBP
当调用fun函数开始时,三者的作用。
1.EIP寄存器里存储的是CPU下次要执行的指令的地址。
也就是调用完fun函数后,让CPU知道应该执行main函数中的printf
("函数调用结束")语句了。
2.EBP寄存器里存储的是是栈的栈底指针,通常叫栈基址,
这个是一开始进行fun()函数调用之前,由ESP传递给EBP的。
(在函数调用前你可以这么理解:ESP存储的是栈顶地址,也是栈底地址。)
3.ESP寄存器里存储的是在调用函数fun()之后,栈的栈顶。并且始终指向栈顶。

当调用fun函数结束后,三者的作用:
1.系统根据EIP寄存器里存储的地址,CPU就能够知道函数调用完,
下一步应该做什么,也就是应该执行main函数中的printf(“函数调用结束”)。
2.EBP寄存器存储的是栈底地址,而这个地址是由ESP在函数调用前传递给EBP的。
等到调用结束,EBP会把其地址再次传回给ESP。所以ESP又一次指向了函数调用结束后,栈顶的地址。
其实我们对这个只需要知道三个指针是什么就可以
楼主你自己调试一下
看看汇编代码就明白了.hh

东莞某某某 2011-06-25
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 long2015 的回复:]

不是函数地址保存哪,而是整个函数实现保存在了一个地方。
编译时,主函数里对于函数的调用 如: add(2,3); 编译时就变成了add函数实现那个地址。
当执行到函数时,直接跳转到那个地址,执行完在跳转回来,接着执行add下面的。
[/Quote]
差不多 核心编程里好像有讲
AnYidan 2011-06-25
  • 打赏
  • 举报
回复
看你调用的什么函数,是标准库吗,现在都是动态连接。运行时才知道函数的内存位置
加载更多回复(11)

70,011

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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