C++:我对return 语句的理解

如果返回的是一个struct对象,return 语句会如何做呢?下面是测试代码

#include <iostream>
using namespace std;
struct Big
{
char buf[100];
int i;
long d;
  }B,B2;
  Big bigfun(Big b)
{
b.i=100;
return b;
}
int main()
{
B2=bigfun(B);
  return 0;
  }
在main开头和结尾设断点
  8: int main()
19: {
004012A0 push ebp
004012A1 mov ebp,esp
004012A3 sub esp,118h
//一开始对这迷惑不解,分析了好久
//原来(118h-40h)剩下的内存块存放了两个Big的变量
//低地址放Bigfun()函数返回值的临时变量
//高地址放B2.operator=(Big &) 的参数
004012A9 push ebx
004012AA push esi
004012AB push edi
004012AC lea edi,[ebp-118h]
004012B2 mov ecx,46h
004012B7 mov eax,0CCCCCCCCh
004012BC rep stos dword ptr [edi]
20: B2=bigfun(B);
004012BE sub esp,6Ch//b参数入栈
004012C1 mov ecx,1Bh
004012C6 mov esi,offset B (00438490)//B的首地址
004012CB mov edi,esp
004012CD rep movs dword ptr [edi],dword ptr [esi]//上面这些指令完成对b的初始化工作
004012CF lea eax,[ebp-0D8h]//eax存放Big类型一个返回值临时变量的首地址
004012D5 push eax//注意一般栈调用没有这条指令
004012D6 call @ILT+0(bigfun) (00401005)
/*
004012DB add esp,70h
004012DE mov esi,eax
004012E0 mov ecx,1Bh
004012E5 lea edi,[ebp-6Ch]
004012E8 rep movs dword ptr [edi],dword ptr [esi]
004012EA mov ecx,1Bh
004012EF lea esi,[ebp-6Ch]
004012F2 mov edi,offset B2 (00438500)
004012F7 rep movs dword ptr [edi],dword ptr [esi]
21:
22: return 0;
004012F9 xor eax,eax
23:
24: }
004012FB pop edi
004012FC pop esi
004012FD pop ebx
004012FE add esp,118h
00401304 cmp ebp,esp
00401306 call __chkesp (004081e0)
0040130B mov esp,ebp
0040130D pop ebp
0040130E ret
*/
@ILT+0(?bigfun@@YA?AUBig@@U1@@Z):
00401005 jmp bigfun (00401250)
  11: Big bigfun(Big b)
12: {
00401250 push ebp
00401251 mov ebp,esp
00401253 sub esp,40h
00401256 push ebx
00401257 push esi
00401258 push edi
00401259 lea edi,[ebp-40h]
0040125C mov ecx,10h
00401261 mov eax,0CCCCCCCCh
00401266 rep stos dword ptr [edi]
13: b.i=100;
00401268 mov dword ptr [ebp+70h],64h
/*
  0012FE50 00 00 00 00 64 00 00 00 00 00 00 00
*/
  14: return b;
0040126F mov ecx,1Bh
00401274 lea esi,[ebp+0Ch]//esi=b的首地址
00401277 mov edi,dword ptr [ebp+8]//edi=返回值临时变量的首地址
0040127A rep movs dword ptr [edi],dword ptr [esi]
0040127C mov eax,dword ptr [ebp+8]
15: }
0040127F pop edi
00401280 pop esi
00401281 pop ebx
00401282 mov esp,ebp
00401284 pop ebp
00401285 ret
  返回到main函数
004012DB add esp,70h//销毁局部参数
004012DE mov esi,eax//bigfunction()返会值临时变量的首地址
004012E0 mov ecx,1Bh
004012E5 lea edi,[ebp-6Ch]//B2.operator=(Big &)参数的首地址
004012E8 rep movs dword ptr [edi],dword ptr [esi]
004012EA mov ecx,1Bh
004012EF lea esi,[ebp-6Ch]
004012F2 mov edi,offset B2 (00438500)//B2的首地址
004012F7 rep movs dword ptr [edi],dword ptr [esi]
21:
22: return 0;
004012F9 xor eax,eax
23:
24: }
004012FB pop edi
004012FC pop esi
004012FD pop ebx
004012FE add esp,118h
00401304 cmp ebp,esp
00401306 call __chkesp (004081e0)
0040130B mov esp,ebp
0040130D pop ebp
0040130E ret

总结:

1.一般function frame的结构是

函数内局部变量

ebp

eip

函数参数

如果返回值是一个struct对象function frame

函数内局部变量

ebp

eip

返回值临时变量的首地址//特别注意这个

函数参数

(由于寄存器太小,不可能放一块struct内存,所以保存了临时变量的首地址)。

2.struct对象的临时变量是在栈上的,而不是在堆上。

时间: 2024-09-13 13:55:27

C++:我对return 语句的理解的相关文章

Java中break、continue、return语句的使用区别对比

  这篇文章主要介绍了Java中break.continue.return语句的使用区别对比,本文用非常清爽简明的语言总结了这三个关键字的使用技巧,并用一个实例对比使用结果,需要的朋友可以参考下 break.continue.return之间的区别与联系 在软件开发过程中,逻辑清晰是非常之重要的. 代码的规范也是非常重要的.往往细节决定成败.在编写代码的时候,一定要理解语言的作用以及使用的方法和场景.下面来介绍一下break.continue.return三者的区别和联系. 1. break :

深入浅析JavaScript中with语句的理解_javascript技巧

JavaScript 有个 with 关键字, with 语句的原本用意是为逐级的对象访问提供命名空间式的速写方式. 也就是在指定的代码区域, 直接通过节点名称调用对象. with语句的作用是暂时改变作用域链.减少的重复输入. 其语法结构为: with(object){ //statements } 举一个实际例子吧: with(document.forms[]){ name.value = "lee king"; address.value = "Peking";

PowerShell中使用return语句退出函数例子_PowerShell

本文介绍在自定义PowerShell函数时,可以使用return语句来退出函数,同时return语句也可以返回值给函数的调用者. 使用return语句来直接退出函数.看一个退出函数的例子: 复制代码 代码如下: function Get-NamedProcess {     param     ($name=$null)     if ($name -eq $null)     {         Write-Host -ForegroundColor Red 'Specify a name!'

方法-关于return语句的一个小白问题,求大神帮助!

问题描述 关于return语句的一个小白问题,求大神帮助! namespace ConsoleApplication34 { class Program { static string k(string b) { string a; a = "你的名字是" +b; return a; } static void Main(string[] args) { Console.WriteLine("输入姓名"); string c = Console.ReadLine()

return 语句

语句   从当前函数退出,并从那个函数返回一个值. return[()[expression][]]; 可选项 expression 参数是要从函数返回的值.如果省略,则该函数不返回值. 说明 用 return 语句来终止一个函数的执行,并返回 expression 的值.如果 expression 被省略,或在函数内没有 return 语句被执行,则把值 undefined 赋给调用当前函数的表达式. 示例 下面示例说明了 return 语句的用法. function myfunction(a

Java中finally语句与return语句的执行次序

Java finally语句到底是在return之前还是之后执行? 网上有很多人探讨Java中异常捕获机制try...catch...finally块中的finally语句是不是一定会被执行?很多人都说不是,当然他们的回答是正确的,经过我试验,至少有两种情况下finally语句是不会被执行的: (1)try语句没有被执行到,如在try语句之前就返回了,这样finally语句就不会执行,这也说明了finally语句被执行的必要而非充分条件是:相应的try语句一定被执行到. (2)在try块中有Sy

PHP return语句另类用法不止是在函数中

  分享下PHP return语句的另一个作用,在bbPress的代码中看到的一个奇葩使用方法. 一直以为,return只能出现在函数中,直到看了bbPress的代码: <?php require_once('./bb-load.php'); bb_repermalink(); // The magic happens here. if ( $self ) { if ( strpos($self, '.php') !== false ) { require($self); } else { re

一个安卓编译器「Bug」引发的血案:调试时method中return语句不能断点问题排查

本周开发安卓时,遇到一个诡异的问题,如下图所示,在调试时部分语句无法执行到,更具体讲,就是method中前几个return语句无法执行到,每次在前面几个return语句要执行时,代码直接就跳到了方法的最后一个return处了,而且这几个return都被打了叉叉,表示无法断点 如何排查? 第一反应自然是安装到真机上的APK包代码与IDEA里面看到的源码不一致 这个思路显然是对的,事实上,开发中经常会遇到APK安装代码与IDEA中代码不一致的情况 怎么验证这个猜想?很简单,在源码里面加上一些特定的调

重复值-oracle 用rowid 取重复的sql语句怎么理解

问题描述 oracle 用rowid 取重复的sql语句怎么理解 这个SQL语句该怎么理解? SELECT * FROM XUTEST X WHERE ROWID!=(SELECT MAX(ROWID) FROM XUTEST Y WHERE y.SUPID=x.SUPID) 解决方案 rowid是表中每条记录的唯一ID.假设XUTEST 表中有3条记录,SUPID为1,2,2 ROWID分别为r1r2r3那么sql相当于 SELECT * FROM XUTEST X WHERE ROWID!=