`

函数返回值研究

    博客分类:
  • C++
 
阅读更多

1.基本类型的返回值

int add(int a, int b)
{
  int c = 0;
  b = c++;
  return a+b;
}

int init()
{
  int a = add(3, 4);
  return a;
}

 对应的汇编如下:

	.file	"list initialization.cpp"
	.text
	.globl	_Z3addii
	.type	_Z3addii, @function
_Z3addii:
.LFB0:
	.cfi_startproc
	pushl	%ebp
	.cfi_def_cfa_offset 8
	.cfi_offset 5, -8
	movl	%esp, %ebp
	.cfi_def_cfa_register 5
	subl	$16, %esp
	movl	$0, -8(%ebp)
	movl	-8(%ebp), %eax
	movl	%eax, -4(%ebp)
	addl	$1, -8(%ebp)
	movl	-4(%ebp), %eax
	movl	8(%ebp), %edx
	addl	%edx, %eax
	leave
	.cfi_restore 5
	.cfi_def_cfa 4, 4
	ret
	.cfi_endproc
.LFE0:
	.size	_Z3addii, .-_Z3addii
	.globl	_Z4initv
	.type	_Z4initv, @function
_Z4initv:
.LFB1:
	.cfi_startproc
	pushl	%ebp
	.cfi_def_cfa_offset 8
	.cfi_offset 5, -8
	movl	%esp, %ebp
	.cfi_def_cfa_register 5
	subl	$24, %esp
	movl	$4, 4(%esp)
	movl	$3, (%esp)
	call	_Z3addii
	movl	%eax, -4(%ebp)
	movl	-4(%ebp), %eax
	leave
	.cfi_restore 5
	.cfi_def_cfa 4, 4
	ret
	.cfi_endproc
.LFE1:
	.size	_Z4initv, .-_Z4initv
	.ident	"GCC: (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3"
	.section	.note.GNU-stack,"",@progbits

 函数默认以%eax作为返回值

看上面add函数的汇编代码,leave语句(即函数返回)的上一句代码:

addl %edx, %eax;即将a+b的值存到%eax寄存器中。接下来再看init中的下面两句汇编代码:

call _Z3addii;调用add函数,调用后%eax寄存器中的值就是add函数的返回值
movl %eax, -4(%ebp);将%eax寄存器的值存入局部变量a中

2.指针类型的返回值

int c = 0;
int* add(int a, int b)
{
  c = a + b;
  return &c;
}

int init()
{
  int *a = add(3, 4);
  return *a;
}

 对应的汇编如下:

_Z3addii:
.LFB0:
	.cfi_startproc
	pushl	%ebp
	.cfi_def_cfa_offset 8
	.cfi_offset 5, -8
	movl	%esp, %ebp
	.cfi_def_cfa_register 5
	movl	12(%ebp), %eax
	movl	8(%ebp), %edx
	addl	%edx, %eax
	movl	%eax, c
	movl	$c, %eax
	popl	%ebp
	.cfi_def_cfa 4, 4
	.cfi_restore 5
	ret
	.cfi_endproc
.LFE0:
	.size	_Z3addii, .-_Z3addii
	.globl	_Z4initv
	.type	_Z4initv, @function
_Z4initv:
.LFB1:
	.cfi_startproc
	pushl	%ebp
	.cfi_def_cfa_offset 8
	.cfi_offset 5, -8
	movl	%esp, %ebp
	.cfi_def_cfa_register 5
	subl	$24, %esp
	movl	$4, 4(%esp)
	movl	$3, (%esp)
	call	_Z3addii
	movl	%eax, -4(%ebp)
	movl	-4(%ebp), %eax
	movl	(%eax), %eax
	leave
	.cfi_restore 5
	.cfi_def_cfa 4, 4
	ret
	.cfi_endproc

 看上面的汇编可以发现,add函数利用语句:

movl $c, %eax;将全局变量c的地址赋值给%eax

init函数利用语句:

movl (%eax), %eax;将%eax寄存器值所代表的地址处的值赋值给%eax

3.引用类型的返回值

int c = 0;
int& add(int a, int b)
{
  c = a + b;
  return c;
}

int init()
{
  int a = add(3, 4);
  return a;
}

 汇编代码如下:

_Z3addii:
.LFB0:
	.cfi_startproc
	pushl	%ebp
	.cfi_def_cfa_offset 8
	.cfi_offset 5, -8
	movl	%esp, %ebp
	.cfi_def_cfa_register 5
	movl	12(%ebp), %eax
	movl	8(%ebp), %edx
	addl	%edx, %eax
	movl	%eax, c
	movl	$c, %eax
	popl	%ebp
	.cfi_def_cfa 4, 4
	.cfi_restore 5
	ret
	.cfi_endproc
.LFE0:
	.size	_Z3addii, .-_Z3addii
	.globl	_Z4initv
	.type	_Z4initv, @function
_Z4initv:
.LFB1:
	.cfi_startproc
	pushl	%ebp
	.cfi_def_cfa_offset 8
	.cfi_offset 5, -8
	movl	%esp, %ebp
	.cfi_def_cfa_register 5
	subl	$24, %esp
	movl	$4, 4(%esp)
	movl	$3, (%esp)
	call	_Z3addii
	movl	(%eax), %eax
	movl	%eax, -4(%ebp)
	movl	-4(%ebp), %eax
	leave
	.cfi_restore 5
	.cfi_def_cfa 4, 4
	ret
	.cfi_endproc

 看上面汇编会发现,add函数还是利用语句:

movl $c, %eax;将全局变量c的地址作为返回值。

但不同的是调用它的函数利用语句:

movl (%eax), %eax;访问到c的值然后赋值给%eax;

 

结论:由此可以发现,函数的返回值都是通过%eax来传递的,且指针类型和引用类型的返回值都是地址值

分享到:
评论

相关推荐

    如何让C++函数返回值死心塌地为你工作

    本文主要研究的是C++函数返回值,你必须注意的问题,下面进入正题。 C++太繁杂了,先接触C++后接触python这样的语言,你就再也不想碰它,因为,就连一个函数返回值都一大堆的说道,这里面的玄机,连工作三年的C++...

    获取JavaScript异步函数的返回值

    今天研究一个小问题: 怎么拿到JavaScript异步函数的返回值? 1.错误尝试 当年未入行时,我的最初尝试: [removed] function getSomething() { var r = 0; setTimeout(function() { r = 2; }, 10); return r; ...

    Python -函数的返回值-接收返回元组函数的方式

    Python由荷兰数学和计算机科学研究学会的吉多·范罗苏姆于1990年代初设计,Python提供了高效的高级数据结构,还能简单有效地面向对象编程。Python语法和动态类型,以及解释型语言的本质,使它成为多数平台上写脚本和...

    Python 函数参数和返回值的作用

    Python由荷兰数学和计算机科学研究学会的吉多·范罗苏姆于1990年代初设计,Python提供了高效的高级数据结构,还能简单有效地面向对象编程。Python语法和动态类型,以及解释型语言的本质,使它成为多数平台上写脚本和...

    Python 函数的返回值-利用元组返回多个值

    Python由荷兰数学和计算机科学研究学会的吉多·范罗苏姆于1990年代初设计,Python提供了高效的高级数据结构,还能简单有效地面向对象编程。Python语法和动态类型,以及解释型语言的本质,使它成为多数平台上写脚本和...

    Python 函数的返回值-03-交换两个变量的值

    Python由荷兰数学和计算机科学研究学会的吉多·范罗苏姆于1990年代初设计,Python提供了高效的高级数据结构,还能简单有效地面向对象编程。Python语法和动态类型,以及解释型语言的本质,使它成为多数平台上写脚本和...

    c语言函数大全及详解 -供大家学习研究参考

    函数原型说明 功能 返回值 说明 int abs( int x) 求整数x的绝对值 计算结果 double fabs(double x) 求双精度实数x的绝对值 计算结果 double acos(double x) 计算cos-1(x)的值 ...

    无随机预言模型下基于模糊身份的签名方案

    与 最 近 Zhan g等人提出的模糊身份签密方案相比,该方案的构造没有采用 Hash函数,避免了 Hash函数返回值无随机性的缺点,且 系统公开参数较少,安全性可规约到 计 算 Diffie -Hellman...

    Python Collatz序列实现过程解析

    然后编写一个程序, 让用户输入一个整数, 并不断对这个数调用 collatz(), 直到函数返回值1(令人惊奇的是, 这个序列对于任何整数都有效, 利用这个序列,你迟早会得到 1! 既使数学家也不能确定为什么。 你的...

    反编译中数据类型重构技术研究

    文环境,得出对应于函数参数和返回值的变量类型,然后通过分析中间语言 BIL 中操作符 的类型特征,制定了基于操作符的类型提取规则,并根据规则得出指令中非函数调用处变 量的类型信息;根据中间语句的不同操作类型...

    【JavaScript源代码】JS实现百度搜索框.docx

    回调函数处理返回值。 尝试研究了一下百度的接口,发现原生的 XHR 接口参数有点复杂(百度应该是考虑了很多情况)。 找了一个 2345 导航,在输入框随便输入一个字母 s,打开 Network,发现它也是向百度的一个地址发送...

    HashTable:这项小型研究的主要目标是找到一个有效的哈希函数并将其实现在哈希表中

    哈希表这项小型研究的主要目标是找到一个有效的哈希函数并将其在我的哈希表中实现。目录准备工作我选择了六个不同的哈希函数来测试并确定哪个哈希表对我的哈希表更好。 这是哈希函数的返回值: 总是返回0 返回第一个...

    盘点Python的内置函数

    最近因为新型冠状病毒的缘故,研究生也推迟开学了,在家里没有科研的动力,平常没事想要摸鱼的时候就写写这个吧,也算是自己系统的学习一下基础。 1.abs() abs()函数,如果括号内为实数,则返回绝对值,如果数字为...

    传智播客扫地僧视频讲义源码

    15_友元函数实现左移右移操作符重载(函数返回值当左值需返回引用)_传智扫地僧 16_友元函数实现操作符重载知识总结 17_重载等号操作符_传智扫地僧 18_数组类小案例_操作符重载需求 19_数组类小案例_重载[]_传智扫地...

    张志晨VB2010实例教程之窗体打印扩展

    经过研究,我编写了一个函数: '窗体打印函数及扩展 Function formPrint(ByVal obj As Object, _ ByVal font As String, _ ByVal fontsize As Double, _ ByVal x As Double, _ ByVal y As Double, _ ByVal ...

    jsalon:JSALON研究资料库

    其返回值仅由参数确定的函数 它使用多个参数,并且如果参数相同,则始终返回相同的值。 纯函数不得在函数外部更改参数或其他变量或执行输入/输出。 主要功能(第一功能类别) 您可以将函数存储在变量中,就像将...

    Ks键盘按键状态监控插件

    很久以前跟一个朋友研究多开单停问题发现按键的 WaitKey GetLastKey 这两个函数用的不怎么习惯所以用VB写了个插件 今天从新弄了下发出来吧 非官方插件模板 只有4个函数 IsKeyDown key 判断某键是否在按下状态...

    吕鑫:【C++语法与数据结构第09天】【第2堂课】各种运算符的重载方法

    1、全面演示C/C++语言内所有运算符的重载方法; 2、研究单双目运算符重载函数的参数和返回值特点; 3、研究类外与类内运算符重载的方法的不同;

    I2C总线协议及模拟软件包

    【函数返回值】 ============================================================ 返回类型 保存在 说明 ------------------------------------------------------------ bit(位) CY byte(字节) ACC word...

    Python中的相关分析correlation analysis的实现

    研究两个或两个以上随机变量之间相互依存关系的方向和密切程度的方法。 线性相关关系主要采用皮尔逊(Pearson)相关系数r来度量连续变量之间线性相关强度; r>0,线性正相关;r<0,线性负相关; r=0,两个变量之间不...

Global site tag (gtag.js) - Google Analytics