`

函数返回值研究

    博客分类:
  • 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; ...

    delphi与JavaScript进行交互,获取JS端返回值

    6. **示例DEMO程序**:`ScriptGate`可能提供了一些示例代码,演示如何设置JavaScript上下文、调用函数以及处理返回值。研究这些示例有助于理解实际操作过程。 通过这样的交互,Delphi应用可以利用JavaScript的灵活...

    用P0 、P1口显示整型函数返回值_单片机C语言实例(纯C语言源代码).zip

    对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步...

    基于C语言实现用P0 、P1口显示整型函数返回值(含源代码+使用说明).zip

    对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步...

    基于C语言实现用P0 、P1口显示整型函数返回值(含源代码+使用说明+毕业设计).zip

    对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步...

    计算机C语言中常用数学函数的研究.pdf

    此外,本文还分析了数学函数参数的应用,例如函数返回值和函数参数返回值的应用。在实际应用中,需要采取诸多方式实现对计算机C语言涉及内容的比较,以掌握所需知识。 在计算机C语言中,数学函数是非常重要的一部分...

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

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

    C语言函数教学方法研究.pdf

    教学中不仅要让学生掌握函数的定义结构,还要让他们理解类型标识符的含义,即函数返回值的类型。 除此之外,文章还提到了虚实结合的教学方法。这种教学策略强调在理论教学的同时,要将理论与实际操作结合起来。通过...

    estimate_MATLABES_

    在MATLAB编程环境中,`estimate`函数通常与信号处理、统计建模或系统辨识相关...在阅读和使用带有“文字程序备注”的`estimate.m`文件时,务必仔细研究这些注释,它们会提供宝贵的指导信息,帮助我们正确地运用该函数。

    关于C语言函数参数应用问题的研究.pdf

    文章通过实例分析和比较,阐述了参数的使用语法、指针参数、数组参数以及函数返回值等多个方面。 首先,C语言中的参数使用语法规定,函数调用时实际参数与形式参数之间进行值的单向传递。这意味着当函数内部对参数...

    20170511_综合研究三研究报告_李智宇1

    综上所述,这份报告深入探讨了C语言的内存管理、变量存储、栈操作、函数返回值的处理以及宏定义和动态内存分配等核心概念。这些知识对于编写高效且安全的C程序至关重要。同时,理解和掌握这些基础可以更好地进行程序...

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

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

    突破C语言中“函数”难点的教学方法.pdf

    函数返回值通过return语句返回,若return语句中不包含变量或表达式,则必须将函数返回值的类型定义为void。 2. 明确函数名:函数名是用户自定义的名称,根据函数名调用函数并执行其中规定的操作。函数名命名应当...

    微软研究院笔试题目的答案..._嵌入式-常用知识&面试题库_大厂面试真题.doc

    在这道题目中,我们看到了函数返回值的使用,例如`return name;`。 10. 字符串操作: 在C++中,字符串操作是通过 strcat、strcpy等函数来实现的。在这道题目中,我们看到了字符串操作的使用,例如`strcat(name, ...

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

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

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

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

    数据结构习题解答(1-8章).doc

    - 可以用函数返回值给其他变量赋值,但要注意赋值时的类型匹配和作用范围。 7. **类的概念**: - 类是对象的模板,它定义了一组具有共同属性和行为的对象。 - 类包含数据成员(属性)和成员函数(方法)。 8. *...

    C语言函数使用的关键问题研究.pdf

    函数类型指明函数返回值的数据类型,若函数无需返回数据,则类型定义为void。函数名是函数的标识符,必须符合C语言的命名规则。形式参数表列出了函数接收的输入参数,各参数必须明确类型和名称,参数之间以逗号分隔...

Global site tag (gtag.js) - Google Analytics