反汇编之C++的const
发布日期:2021-05-26 20:04:55
浏览次数:13
分类:技术文章
本文共 2205 字,大约阅读时间需要 7 分钟。
#include<iostream>
#include<stdlib.h>
using namespace std;
const int &add( const int &a,const int &b)
{
return a+b;
}
int main()
{
const int &result = add(5,8);
add(11, 8);//重复使用栈.排除虽然栈回收.但值没变的可能性
add(5, 8);
- add(5,8);
- add(5,8);
- add(5,8);
cout << result << endl;
system("pause");
return 0;
}
以上结果输出13.原因在于当add的时候参数5,8.将生成2个临时对象(但这个临时对象的生存周期可伴随main).用来保存5,8
main.c 部分反汇编代码
00FC18CE mov dword ptr [ebp-0D4h],8 ;创建一个地址用来保存8
00FC18D8 mov dword ptr [ebp-0E0h],5 ;创建一个地址用来保存5
00FC18E2 lea eax,[ebp-0D4h] ;将保存8的地址赋给eax.
00FC18E8 push eax ;地址压栈
00FC18E9 lea ecx,[ebp-0E0h] ;将保存5的地址赋给ecx
00FC18EF push ecx ;将地址压入栈中
00FC18F0 call add (0FC138Eh)
00FC18F5 add esp,8 ;回收栈
00FC18F8 mov dword ptr [result],eax
const int &add(const int &a, const int &b)
{
002217C0 push ebp
002217C1 mov ebp,esp
002217C3 sub esp,0CCh ;开辟局部栈空间,大小为0cch
002217C9 push ebx
002217CA push esi
002217CB push edi
002217CC lea edi,[ebp-0CCh] ;
002217D2 mov ecx,33h
002217D7 mov eax,0CCCCCCCCh
002217DC rep stos dword ptr es:[edi]
注意.以上局部栈空间大小在 esp到esp-0cch之间.当函数调用完此空间将回收(并不是真正意义的回收.只是改变栈指针罢了.原来的数值还在.不过如果此栈被反复调用(这就是为何我重复调用的原因).栈的数据当然改变)
0
0FC17DE mov eax,dword ptr [a] ;将临时对象5的地址赋给eax (const int &a) [a]保存的是临时对象5的00FC17E1 mov ecx,dword ptr [eax] ;将eax保存的值给ecx
00FC17E3 mov edx,dword ptr [b] ;将临时对象b的地址赋给edx
00FC17E6 add ecx,dword ptr [edx] ;将edx保存的值加到ecx中
00FC17E8 mov dword ptr [ebp-0C8h],ecx ;将结果保存到ebp-0c8h中(临时对象)
00FC17EE lea eax,[ebp-0C8h] ;将结果地址赋给eax
}
- 执行完Add函数后将临时对象的地址保存到result引用中
00FC18F8 mov dword ptr [result],eax
注意了 return a+b;开辟的临时对象在ebp-0c8h处.处于局部栈之内!!!(ebp~ebp-0xcch).当add调用完后..将此回收地址赋给了result引用.于是出现了结果乱了的情况了
2.初始化一个常量引用所引发的临时对象
当初始化一个常量引用(const reference)时,如果给定的初始化对象类型与目标引用类型不同(但是两者 能够相互转换),需要产生临时对象;
对于局部const int temp=10这类变量.即使取地址使得其改变也不会有任何变化.
double db=10.000;
int &q=db;
以上会报错.
因为实际他会转化为 int temp=(int) db; int &a=temp;.本意是想通过a可以改变db.但实现却不可以改变(改变的是Temp).因此.编译器将会报错
当然如果是 const int &a=db;这样编译器将不会报错.因为const修饰这个temp(db)不会改变的
double db = 10;
00EB1868 movsd xmm0,mmword ptr ds:[0EB6B38h]
00EB1870 movsd mmword ptr [db],xmm0
const int &q = db;
00EB1875 cvttsd2si eax,mmword ptr [db] ;db的值10赋给eax
00EB187A mov dword ptr [ebp-28h],eax ;将eax赋给ebp-28h(就是临时对象)
00EB187D lea ecx,[ebp-28h]
00EB1880 mov dword ptr [q],ecx
- 转自
转载地址:https://blog.csdn.net/Gaodes/article/details/81701940 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
很好
[***.229.124.182]2024年04月13日 02时26分22秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
【力扣】456. 132 模式
2021-06-29
【力扣】82. 删除排序链表中的重复元素 II
2021-06-29
【剑指OFFER】 41. 数据流中的中位数
2021-06-29
【力扣】83. 删除排序链表中的重复元素
2021-06-29
【剑指OFFER】 43. 1~n 整数中 1 出现的次数
2021-06-29
【剑指OFFER】44. 数字序列中某一位的数字
2021-06-29
【剑指OFFER】45. 把数组排成最小的数
2021-06-29
【区块链】使用JAV简易A模拟创建区块链及挖矿
2021-06-29
【力扣】74. 搜索二维矩阵
2021-06-29
【剑指OFFER】46. 把数字翻译成字符串
2021-06-29
【剑指OFFER】47. 礼物的最大价值
2021-06-29
【力扣】90. 子集 II
2021-06-29
【剑指OFFER】48. 最长不含重复字符的子字符串
2021-06-29
【力扣】80. 删除有序数组中的重复项 II
2021-06-29
【剑指OFFER】50. 第一个只出现一次的字符
2021-06-29
【剑指OFFER】57 - II. 和为s的连续正数序列
2021-06-29
【Java】 用PriorityQueue实现最大最小堆
2021-06-29
【剑指OFFER】49. 丑数
2021-06-29
【力扣】179. 最大数
2021-06-29
【剑指OFFER】56 - I. 数组中数字出现的次数
2021-06-29