社区
C语言
帖子详情
函数的地址都是保存在哪里?
motiandalou
2011-06-25 02:30:00
调用函数时,程序怎么知道应该跳转到函数的定义处,函数的地址都是保存在哪里?是寄存器区、程序代码区还是栈中。
...全文
3048
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)
尹成Python27天入门到项目实战
尹成Python27天从入门到实战项目!全课665节讲解详细易操作,助力实战项目能力成长,轻松、简单、易懂!day1 python入门与学习方法精确思维与用到才能记忆深刻课程简介课前介绍计算机简介与硬盘概念内存作用计算机小结编程语言简介操作系统简介python版本简介切换python版本修改环境变量交互式编程两种风格python3代码
保存
必须是utf-8使用IDE了解注释段落打印三引号注释多行三个单引号python代码要严格对齐中文输入字符错误简单数学表达式代码风格三种错误风格系统执行指令运行结果乱码交互式编程绘图绘制线段与圆形改变颜色绘制奥运五环小结习题day1plus python 常量变量数据类型 常量与变量区别标识符关键字输入输出id求
地址
type求类型python变量是
地址
赋值可以改变类型python主要数据类型复数数据类型自适应变长整数intdel作用连续赋值交互对称赋值字符串转化与输入输出编程wmv多行拆分多行归并成一行规范用的常量算术运算符科学计数法与数字越界优先级结合性赋值运算符数据类型转换四舍五入数据提取时间处理作业day2 python字符串与绘图复习变量None变量参与运算没有赋值的情况不会改变绘制立方体绘制五角星时间计算强化实现贷款计算连续输入多个字符串加法与绘图实现显示线段长度数据
函数
使用快速查阅
函数
帮助字符串三种风格字符与编号中文字符编号问题字符编号用途统一码转义字符意义转义字符用于字符串print高级用法字符串加法与转换字符串小结python中所有的数据都是对象字符串格式化了解进制图形绘制重点作业以及学习认知方法day3 python运算符与ifelse逻辑语句第一天上午回顾第二天下午回顾1第二天回顾2.7习题解答2.11习题解答2.26作业KaliLinux简介3.4实现五边形面积计算3.7随机字符生成3.8实数误差与四舍五入3.18解答与特殊字符if简介与空格的作用if处理的是逻辑表达式关系运算符针对数值字符串的关系运算符if自动转化Bool类型随机数if缺点且运算符或运算符取反运算符短路效应身份运算符运算符优先级结合性概览pass语句潜台词翻译系统None用途指令翻译系统嵌套嵌套与elif对比以及注意细节习题解答绘图作业与重点day4 语音合成与逻辑循环回顾语音合成简单理解while控制次数WhileElseWhileElse实战whileFloat回顾与ifelse表达式赌博概率分类设计方法-一元二次方程嵌套求有序3个数闰年计算矩形区域随机数ifelse回文数判断10进制转化16进制16进制转十进制暴力穷举无限循环指令循环同步异步黑科技读写内存读写内存无限循环监测重点与作业day5 复杂逻辑循环while与whileelse编程风格循环控制图形绘制while猜数字输入输出重定向while习题分析可以退出的命令系统for初步简介跑分流程结合for循环小结forfor嵌套forfor分析break中断循环contiune结束本次循环双层循环的break与continue分析break与contiue小结一闪一闪亮晶晶循环控制大小与位置对角线绘制圆形口顺时针运动循环等价作业与小结day6
函数
实战回顾.算学费输入数据求最大精确划分思维解决最大次大交换数据实现按行显示围棋棋盘绘制国际象棋绘制为什么要用
函数
函数
的四种类型
函数
的一般形式必须用
函数
的理由-哥德巴赫
函数
的本质就是
地址
函数
变量意义
函数
变量用途装饰器设计模式包含模式
函数
概念None
函数
默认参数与返回值作为参数名称参数与位置参数参数副本机制副本练习多个返回值全局变量与局部变量
函数
内部引用全局变量
函数
可以嵌套nolocal处理
函数
嵌套变量
函数
nonlocalnonlocal总结开房数据查询day7
函数
实战与常用数据结构
函数
的两种类型
函数
的本质再分析
函数
地址
切换切换功能ifelse配合
地址
筛选
函数
收费
函数
调用过程
函数
基本小结return小结位置参数与默认参数混合参数填充混合填充错误情况lambda匿名
函数
可变长
函数
字符串常识普及字符串特点字符串不可以修改内部字符list列表list用途tuple简介集合运算字典概念in与notin运算符构造表达式转换数据类型系统小结拓展查询作业day8 字符串实战简单回顾eval与exec简介字符串的简单规范字符串的截取字符串赋值规范字符串转义字符字符串常见运算符字符串格式化字符串格式化强化字符串编码简介dir与help查看str字符串
函数
第一个大写以及字符串居中显示打印金字塔count统计字符串出现个数字符串编码注意事项解码失败判断字符串以什么为结束tab键转换find
函数
与rfind
函数
day9 字符串高级简单回顾..eval与exec简介字符串的简单规范字符串的截取字符串赋值规范字符串转义字符字符串常见运算符字符串格式化字符串格式化强化字符串编码简介dir与help查看str字符串
函数
第一个大写以及字符串居中显示打印金字塔count统计字符串出现个数字符串编码注意事项解码失败判断字符串以什么为结束tab键转换find
函数
与rfind
函数
index
函数
与rindex
函数
字符串判断字符串间隔求长度以及左右填充字符串大小写取出最大最小字符替换去除空格简单切割换行切割判断开头大小写切换以及填充0翻译表.字符串模板小结day10 字符串集合与语音识别实战回顾lset初始化风格set增加与去重set删除元素遍历set类型转化set无法操作单个元素的赋值set常见方法set常见运算符set关系运算符判断包含set集合判断frozenset字典的基本定义循环字典判断在不在实现插入与更新字典删除字典详解字典与set无法嵌套迭代器列表生成式生成器生成器节省内存用于循环生成器yield作用生成器简介测试游戏简介游戏初级修改键盘模拟语音控制游戏实现鼠标模拟代码规范
函数
简化重用列表与元组小结作业day11 阶段综合练习昨日回顾.堆栈
函数
模块引用系统模块引用与错误列表生成式的若干方法生成矩阵str与reprpython把输入输出设备当作文件处理写入中文写入英文读取中文读取英文读取错误写入错误处理文件缓存区文件读取若干种方式for循环按行读取数据文件指针seektell数据结构与文件的交互数据查询并
保存
结果数据查询小结与数据day12downwithoutdata 数据处理开发大数据指令数据清洗的概念初级数据清洗密码排序次数统计QQ密码概率分布QQ号码分类器.开房数据清洗..区域划分省份划分年龄月份划分日划分day12up 数据实战简单回顾12系统默认编码中文编码常见错误字符串切割抓取邮箱抓取用户名与密码排序密码文件统计次数排序.统计文件密码次数密码次数排序day13withoutdata 数据分类与list深入地区分类详解字典分类器数据简单归并数据如何切割数据加密数据解密指令执行判断文件夹编程小结列表归并-删除列表归并-下标小结与作业day14down 面向对象编程与深浅拷贝面向对象与过程的差异self用途动态绑定增加属性方法重载运算符的概念有名对象与匿名对象重载运算符的返回值重载运算符多个类型类的拷贝是浅复制深浅拷贝
函数
调用参数副本原理
函数
调用可以改变list的元素不可以改变list指向对象当作参数的细节私有变量私有变量用于设计权限私有方法用于设计权限私有变量本质用类的方式读取文件行数密码次数归并数据处理方法简介今日小结作业wmvday14up 暴力穷举与类回顾....排列组合暴力生成穷举密码密码破解必破生成器密码破解小结为啥使用类-代码重用类的一般形式详解self构造
函数
与析构
函数
构造
函数
初始化类的属性最简洁的UI设定窗体的位置以及大小类的实际用途day15down 面向对象数据搜索实战输入处理文本编辑器表格数据树状显示数据搜索可视化第一步实现查询窗体数据搜索可视化第二步实现搜索数据数据搜索可视化第三步实现显示窗体数据可视化第四步显示与搜索串联数据可视化终结作业小结day15up 面向对象设计与图像界面上设计一个类发短信类的方法设计一下短信发送邮件类的设计-设计发邮件类的多文件引用腾讯营销类的设计消息循环消息回掉
函数
机制lambda按下按钮标签显示文本文本输入框listcombobox选择列表day16up 面向对象与图形界面开发下设计一个类发短信类的方法设计一下短信发送邮件类的设计-设计发邮件类的多文件引用腾讯营销类的设计消息循环消息回掉
函数
机制lambda按下按钮标签显示文本文本输入框listcombobox选择列表day17 面向对象继承实战昨日小结.,.继承的概念多继承的概念多继承的覆盖私有变量不可以被继承Object类类的常见属性super解决父类重复初始化isinstance多态静态方法类方法数据工具1类的继承数据工具实现小结day18down 正则表达式正则表达式bB贪婪与非贪婪标签.标签解决提取标签名称提取QQ生成邮箱列表工具简单正则表达式编写常见的正则表达式复杂正则表达式编写复杂表达式代码验证作业与小结day18up 正则表达式实践为什么使用正则表达式正则表达式匹配.预编译的概念搜索技能搜索用在找出第一个邮箱手机提取findall字符串切割筛选正则表达式正则表达式替换单个字符判断中括号选择一个字符正则表达式次数正则开头结尾括号与选择正则表达式特殊符号day19down 递归与爬虫实战
函数
递归模拟文件树文件树事件读取网页抓取邮箱抓取QQ提取http抓取邮箱简单程序框架实现抓取邮箱的框架核心两个
函数
完成广度遍历深度遍历作.业day19up 深度遍历与广度遍历正则表达式小结最简单递归递归顺序递归求和递归腾讯台阶面试题文件夹的
函数
遍历文件夹遍历文件夹有层次感栈模拟递归栈模拟递归遍历文件夹栈模拟递归遍历文件夹层次感普及网站提取概念栈修改的逻辑错误广度遍历 day20 正则 爬虫实战行情简介提取页面信息提取股票代码提取股票代码下载功能下载股票批量下载股票抓取1页的股票数据抓取多个页面的股票抓取基金信息作业day21 网络编程与信息安全网络概念UDP协议UDP通信UDP远程控制TCP通信TCP控制测试网站后台网站密码破解作业 day22down 线程通信线程通信线程通信强化线程condition高级线程调度生产者消费者线程池延时线程with作用前台进程后台进程TLS线程独立存储作业day22up 多线程实战多线程核心目标并发主线程与小弟线程多线程解决加速多线程的加速线程冲突基于类实现多线程基于类实现多线程的顺序与乱序互斥锁解决线程冲突死锁-使用锁要注意Rlock解决一个线程反复加锁单线程死锁创建线程的三种风格信号量限制线程数量限定线程数量day23 多进程实战多线程回顾多进程拷贝代码多进程拷贝全局变量获取进程编号subprocess执行LinuxShell信号Linux进程小结__name__进程mutiprocessing创建过程join作用进程不可以用全局变量共享数据进程同步进程pipe发送接收数据进程队列进程队列传输数据进程共享数据进程之间共享数组进程共享字典与list简单小结day23down 多进程多线程综合实战读取CSV写入csv单线程统计行数多线程统计行数多进程统计行数多线程检索数据第一步多线程检索赵琳多线程检索找到通知其他人退出多线程检索开放数据并
保存
同一个文件作业day24up 多进程多线程综合实战多进程检索第一步多进程检索开房数据求平均市值多线程解决平均市值多进程统计平均市值单线程BFS抓取邮箱多线程并行抓取邮箱多线程采集邮箱并
保存
csv归并多线程归并文件day25down 文件格式处理doc处理系统处理doc与docx文件处理的小结读取并写入xls与xlsx读取网络pdf中文pdftelnet简介登陆Linux登陆Windows小结day25up 时间编程与单元测试时间的简单风格时间格式化抓取年月日计算时间差时间
函数
计算时间差date小结python2与3的差异内置
函数
筛选内置
函数
map内置的
函数
sorted新浪数据抓取实时文档测试单元测试
函数
单元测试一个类day26 综合实战播放音乐设置背景鬼程序协程简介协程传递数据wmv协程编号协程生产者消费者模式office自动化操作wordoffice办公自动化操作exceloffice办公自动化操作outlookoffice办公自动化access开发环境配置访问mdb格式访问accdb格式实现CGI程序显示页面环境变量cgi处理前后端day26down 破解wifi实战扫描wifi扫描网卡区分链接成功或者失败wifi密码爆破工具设计Linux破解简介day27down 飞机大战实战命令行下脱裤创建一个pygame窗体窗体加载背景图片处理消息飞机移动实现基本框架飞机框架飞机销毁双机对战双机对战加载子弹双机与敌机出现发射子弹day27up 数据库实战jython的安装MySQL简介数据库的一般操作MySQL数据类型数据表的创建于删除数据的查询数据的插入数据的删除数据的更新联合查询字段一致数据查询排序排序与分组join与nullmysql用python编程查询数据python数据库增删查改项目简介other 异常与错误综合练习异常与错误的概念作业tryexcept解决异常不出错继续执行密码破解工具进攻数据库爆破mysql异常else异常处理的标准公式弹出异常withas类中使用异常继承自定义异常断言密码工具设计三个独立的类密码工具2类链接3类密码工具1类链接3类密码工具分析作业speech 语音识别问题解决语音识别解决None
函数
的返回值
保存
在哪里
函数
的返回值
保存
在内存的什么区域呢? 1、结构体大小不超过4字节,那么仍然使用EAX寄存器传递返回值 2.结构体超过4字节但不等于8字节时,调用者将首先在栈上分配一块能容纳结构体的临时内存块,然后在传递完
函数
参数后将该临时内存块的首
地址
作为隐含的第一个参数最后(因为压栈顺序是从右到左)压栈,接下的动作同前所述。当被调用
函数
返回时,它会通过第一个隐含参数寻址到临时内存块并将返回值拷贝到其中,然后将
保存
有返回值内容的临时内存块的首址存进eax寄存器中, 3、结构体大小刚好为8个字节时编译器不再于栈上分配内存,而
函数
的返回值存放在哪里
函数
的返回值存放在哪里 调用
函数
时,
函数
的返回值存放的位置具体在哪里呢?按照概念来说,
函数
的返回值应该放在被调用
函数
运行结束之后,主调
函数
可以有效访问的地方,也就是说,
函数
返回值应当存放在主调
函数
开辟的栈空间 但是,计算机硬件的飞速发展使得CPU的通用寄存器字长在不断增长,个数也不断增多,因此在很多情况下,
函数
的返回值直接被存放在了CPU的通用寄存器中,而并非一定需要计算机的内存空间 具体类型的返回值的存放位置如下所示: char(8bit):寄存器a1 short(16bit):寄存器ax int(32
什么是递归
函数
?
递归
函数
递归 例题 特点 效率 优点 递归
函数
递归 递归就是一个
函数
在它的
函数
体内调用它自身。执行递归
函数
将反复调用其自身,每调用一次就进入新的一层。递归
函数
必须有结束条件。 当
函数
在一直递推,直到遇到墙后返回,这个墙就是结束条件。 所以递归要有两个要素,结束条件与递推关系 注: 递归的时候,每次调用一个
函数
,计算机都会为这个
函数
分配新的空间,这就是说,当...
函数
栈到底是怎么工作的?
参考 https://blog.csdn.net/amghost/article/details/38053101 一些细节 局部变量是存储在堆栈中的:
函数
当中的局部变量参数都是在
函数
栈上的局部变量,main
函数
当中的局部变量都是在main
函数
栈上的。 在intel x86的系统中,堆栈在内存中是从高
地址
向低
地址
扩展:栈顶是栈当中
地址
最低的地方。 在32位系统中,堆栈每个...
C语言
69,382
社区成员
243,073
社区内容
发帖
与我相关
我的任务
C语言
C语言相关问题讨论
复制链接
扫一扫
分享
社区描述
C语言相关问题讨论
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章