社区
C语言
帖子详情
函数值的存储空间是如何分配的?
OneMoreFreeMan
2005-03-12 08:17:35
哪位大侠能详细讲述一下函数值的存储空间是如何分配的。特别是当有值返回的函数,而又不被读去时,则返回的值被存储在何处。
...全文
199
10
打赏
收藏
函数值的存储空间是如何分配的?
哪位大侠能详细讲述一下函数值的存储空间是如何分配的。特别是当有值返回的函数,而又不被读去时,则返回的值被存储在何处。
复制链接
扫一扫
分享
转发到动态
举报
写回复
配置赞助广告
用AI写文章
10 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
dongpy
2005-03-13
打赏
举报
回复
特别是当有值返回的函数,而又不被读去时,则返回的值被存储在何处
===================================
如果函数返回值类型不大于寄存器的宽度,即小于等于32位。
那么返回值放在寄存器eax带出函数。
如果返回值类型大于32位,那么返回值的地址放在寄存器eax带出函数。
yuanyou
2005-03-13
打赏
举报
回复
学习!
tabris17
2005-03-13
打赏
举报
回复
上次说了一个C++对象在内存中的实际形式,现在来说说C++中以对象为参数或返回值的函数是如何实现的。在此之前如果你对函数调用的汇编形式毫无概念的话可以先看看这篇文章:http://www.20cn.net/ns/wz/sys/data/20040208183412.htm
来看下面的代码:
class test //sizeof(test) is 24
{
public:
int m1;
int m2;
int m3;
int m4;
int m5;
int m6;
};
test function1()
{
test cls2;
return cls2; // Line 15
}
int function2(test temp)
{
temp.m1=1; // Line 20
return 0; // Line 21
}
int main()
{
test cls1;
cls1=function1(); // Line 27
function2(cls1); // Line 28
return 0;
}
由于VC编译的未优化代码和优化后的代码相差比较大,所以在编译时增加"/02"参数,使用命令行"cl test.cpp /Fa /02"对源文件进行编译。得到的中间汇编代码如下:
PUBLIC ?function1@@YA?AVtest@@XZ ; function1
; COMDAT ?function1@@YA?AVtest@@XZ
_TEXT SEGMENT
_cls2$ = -24
$T295 = 8
?function1@@YA?AVtest@@XZ PROC NEAR ; function1入口
; File main.cpp
; Line 15
mov eax, DWORD PTR $T295[esp-4] ; 将cls1的地址作为返回值保存到eax中
sub esp, 24 ; 分配cls2的内存
mov ecx, 6
push esi
push edi
lea esi, DWORD PTR _cls2$[esp+32]
mov edi, eax
rep movsd ; 将cls2对象复制到cls1中去
pop edi
pop esi
; Line 16
add esp, 24 ; 00000018H
ret 0
?function1@@YA?AVtest@@XZ ENDP ; function1结束
_TEXT ENDS
PUBLIC ?function2@@YAHVtest@@@Z ; function2
; COMDAT ?function2@@YAHVtest@@@Z
_TEXT SEGMENT
?function2@@YAHVtest@@@Z PROC NEAR ; function2入口
; Line 21
xor eax, eax ; Line 20 的操作被优化掉了
; Line 22
ret 0
?function2@@YAHVtest@@@Z ENDP ; function2结束
_TEXT ENDS
PUBLIC _main
; COMDAT _main
_TEXT SEGMENT
$T301 = -24
_main PROC NEAR ; COMDAT
; Line 25
sub esp, 24 ; 分配cls1的内存空间
; Line 27
lea eax, DWORD PTR $T301[esp+24] ; 将cls1的地址送入eax寄存器
push esi
push edi
push eax ; 将cls1的地址作为参数传递给function1
call ?function1@@YA?AVtest@@XZ ; 调用function1
; Line 28
sub esp, 20 ; 恢复堆栈并分配temp对象的空间(24-4=20)
mov ecx, 6
mov esi, eax
mov edi, esp
rep movsd ; 将cls1对象复制到temp对象中去
call ?function2@@YAHVtest@@@Z ; 调用function2
add esp, 24 ; 00000018H
; Line 29
xor eax, eax
; Line 30
pop edi
pop esi
add esp, 24 ; 00000018H
ret 0
_main ENDP
_TEXT ENDS
END
先来看function1的调用过程:1)程序现在堆栈中给cls1分配了24字节的内存;然后将cls1的地址作为参数传递给function1;随后调用function1。2)进入function1中,程序先给cls2分配内存;然后程序将cls2对象复制到cls1中去;把cls1的地址作为返回值。
根据上述过程,"test function1();"的实际形式其实是:
test *function1(test *ptr_cls)
{
test cls2;
memcpy(ptr_cls,&cls2,sizeof(test));
return ptr_cls;
}
而调用代码的实际形式是:
int main()
{
test cls1;
function1(&cls1);
... ...
return 0;
}
再来看function2的调用过程:程序先给temp分配了一个24字节的对象;然后将cls1对象复制到temp对象中去;随后就调用function2。比起function1,function2要简单很多。
lovefly_fanny
2005-03-12
打赏
举报
回复
上面提醒我了,不够严密
指的堆栈是进程堆栈区区别于系统堆栈
谁再来补充,学习···^_^
lovefly_fanny
2005-03-12
打赏
举报
回复
当从主程序进入到一个函数的时候,堆栈中增加一个元组,
存放临时变量,也包括返回值。
当程序返回后,就从堆栈中退栈。如果返回值被赋给某个主调
程序中的变量时,实际上是调用了copy constructor按bite复制了返回值到
主调程序的变量中,(如果自己定义了该类型的copy构造函数的话,就调用
自己定义的copy构造函数把函数的返回值复制到主调程序的变量中)
当这个过程完成后,栈顶元素被释放,这样包括函数中的临时变量和返回值
都被释放掉了。
****************************************
返回值是不可能放在堆栈里的。。。
想想看,当一个函数返回的时候
如果把返回值放在堆栈中,由于
返回函数必须pop到函数返回地址(也就是在函数调用的时候
push进去的地址),而x86机子中堆栈的生长方向是
向下的,必然的这里 你所谓的”返回值“就在返回地址的
下面了,这样在pop的过程中已经将返回值抹去了,也就不存在
返回值拷贝的可能了。
个人认为,返回值作为一个临时变量,由于有返回对象的可能,
所以返回值的地址应该放在寄存器中,临时变量在赋值或者拷贝构造之后
自动清除。。。
yuchengliu
2005-03-12
打赏
举报
回复
有的放在EAX中
有的是系统栈
其他的我没有自己亲自见过!
CharlieBrown
2005-03-12
打赏
举报
回复
另外,如果函数返回值是自己new出来的话,这个在函数返回后都不被清除,
就要自己手动释放。。
CharlieBrown
2005-03-12
打赏
举报
回复
当从主程序进入到一个函数的时候,堆栈中增加一个元组,
存放临时变量,也包括返回值。
当程序返回后,就从堆栈中退栈。如果返回值被赋给某个主调
程序中的变量时,实际上是调用了copy constructor按bite复制了返回值到
主调程序的变量中,(如果自己定义了该类型的copy构造函数的话,就调用
自己定义的copy构造函数把函数的返回值复制到主调程序的变量中)
当这个过程完成后,栈顶元素被释放,这样包括函数中的临时变量和返回值
都被释放掉了。
jsunnygirl
2005-03-12
打赏
举报
回复
我觉的返回的值只是临时变量,应该在堆栈中吧
特别是当有值返回的函数,而又不被读去时,则返回的值没有存储空间.
就像一个函数内的局部变量,函数退出后就没了
nodummy
2005-03-12
打赏
举报
回复
按照cdecl协议的要求,函数的返回值是放在eax寄存器的
另外什么叫函数值?函数返回值?好像不太像……
跟宁哥学Go语言视频课程(4):
函数
本课程的主要内容: 1.
函数
声明 2.
函数
递归 3. 多返回
值
4. 错误处理 5.
函数
值
6. 匿名
函数
7. 迭代变量陷阱 8. 可变参数 9.
函数
延迟调用(defer) 10. 触发panic异常 11. 模拟try catch语法
python返回
函数
值
并退出
函数
_Python基础:Python
函数
函数
定义的简单规则 :1、用def定义,接着是
函数
名和参数和冒号,格式:2、
函数
内部代码块需要缩进3、使用return返回
函数
值
,默认返回
值
是None格式:def
函数
名(参数) :代码块return #可有可无,也可以在代码块任意...
输出
函数
f(a,b)=2×a2+b2的最小的100个
函数
值
及相应的两个参数的
值
(1)作为
函数
值
的存储结构应尽可能节省空间。 (2)所设计算法及整个程序的时间复杂度应尽可能小。 思路: 遍历每一个数result,找到符合2*a^2+b^2==result的a和b,下面代码中在0~50中找a和b,本题中可以缩小搜索...
C++
函数
值
的调用 & C++语法
无返回
值
函数
(void
函数
) void
函数
的定义 不带返回
值
的return语句只能用于返回类型是void的
函数
。在返回类型为void的
函数
中,return...示例一:交换两个整形变量数
值
的
函数
void swap(int & a, int & b)
数据结构笔记(十三)-- 串的堆
分配
存储表示
堆
分配
内存仍是一组地址连续的存储单元来存放串
值
字符序列,但是
存储空间
实在程序执行过程中动态
分配
而得。在C语言中,存在一个称为“堆”的自由存储区,并由C语言的动态
分配
函数
malloc()和free()来管理。利用
函数
...
C语言
69,373
社区成员
243,079
社区内容
发帖
与我相关
我的任务
C语言
C语言相关问题讨论
复制链接
扫一扫
分享
社区描述
C语言相关问题讨论
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章