c++(vs上)与g++(linux下)对于++操作的汇编代码解读
先来看一个代码,估计很多同学都碰到过其中的某一个。
#include <stdio.h>
#include <iostream>
using namespace std;
int main()
{
int a = ;
printf("a++ = %d\n", a++); a = ;
printf("++a = %d\n", ++a); a = ;
printf("a += a++ =%d\n", a += a++);
a = ;
printf("a += (a++) =%d\n", a = a + (a++)); a = ;
printf("a += ++a =%d\n", a += ++a);
a = ;
printf("a += (++a) =%d\n", a += (++a)); a = ;
printf("++a += a++ =%d\n", ++a += a++);
a = ;
printf("(++a) += (a++) =%d\n", (++a) += (a++)); return ;
}
估计很多同学都饱受摧残(T-T)。
更坑的是,卧槽不同编译器下会有不用的结果。(╯°口°)╯(┴—┴
a.VS2013下的运行结果
b.g++下的运行结果
从结果可以看出,除了最开始两个书本上教的a++与++a是一致的(a++是先取a值然后再执行a=a+1,++a是先a = a+1,在取a的值)外,其他很多都不相同。
(゚Д゚≡゚д゚)!? 这也能玩? 百思不得其姐,打开汇编代码一探究竟。
先来看下vs下的汇编(拍下脑子想下大一学的汇编):
/* vs2013 */
: printf("a += a++ =%d\n", a += a++);
011ECAC7 mov eax,dword ptr [a] //把a的值放入eax寄存器中
011ECACA add eax,dword ptr [a] //把a的值加到eax中(eax = eax+a )
011ECACD mov dword ptr [a],eax //把eax的值放入a, 以上就是 += 的操作
011ECAD0 mov ecx,dword ptr [a] //把a放入ecx寄存器中
011ECAD3 mov dword ptr [ebp-0D0h],ecx //直接打印了。。。--! 也就是忽略了a++ 直接打印了
011ECAD9 mov edx,dword ptr [a] //接下来就是执行a++,以及以下基础操作了。
011ECADC add edx,
011ECADF mov dword ptr [a],edx
011ECAE2 mov esi,esp
011ECAE4 mov eax,dword ptr [ebp-0D0h]
011ECAEA push eax
011ECAEB push 11F832Ch
011ECAF0 call dword ptr ds:[11FC1E4h]
011ECAF6 add esp,
011ECAF9 cmp esi,esp
011ECAFB call __RTC_CheckEsp (011E1631h)
简单的分析了,发现vs中a++的操作放在最后面执行。
再来瞧瞧g++的汇编代码:
g++下汇编和vs下汇编有很大不同,最大的一个是
vs: mov a,b 指将b->a
g++: mov a,b 指将a->b
(我改了下顺序,你就不能说我抄袭了吧c++(vs上)与g++(linux下)对于++操作的汇编代码解读的更多相关文章
- SSL握手通信详解及linux下c/c++ SSL Socket代码举例(另附SSL双向认证客户端代码)
SSL握手通信详解及linux下c/c++ SSL Socket代码举例(另附SSL双向认证客户端代码) 摘自: https://blog.csdn.net/sjin_1314/article/det ...
- Linux下读写UART串口的代码
Linux下读写UART串口的代码,从IBM Developer network上拿来的东西,操作比較的复杂,就直接跳过了,好在代码能用,记录一下- 两个实用的函数- //////////////// ...
- Linux下9种优秀的代码比对工具推荐
大家好,我是良许. 在我们编写代码的时候,我们经常需要知道两个文件之间,或者同一个文件不同版本之间有什么差异性.在 Windows 下有个很强大的工具叫作 BeyondCompare ,那在 Linu ...
- SSL握手通信详解及linux下c/c++ SSL Socket代码举例
SSL握手通信详解及linux下c/c++ SSL Socket代码举例 摘自:http://www.169it.com/article/3215130236.html 分享到:8 发布时 ...
- Azure上如何在Linux下挂载数据磁盘
[原文首次发表于51cto http://cloudapps.blog.51cto.com/3136598/1653672] 在Azure上创建了虚拟机之后,我们在一些情况下会需要添加更多的数据磁盘来 ...
- Windows、Linux下文件操作(写、删除)错误的产生原因、及解决方法
catalog . 引言 . Linux平台上涉及的File IO操作 . Windows平台上涉及的File IO操作 0. 引言 本文试图讨论在windows.linux操作系统上基于C库进行文件 ...
- Nginx入门篇-基础知识与linux下安装操作
我们要深刻理解学习NG的原理与安装方法,要切合实际结合业务需求,应用场景进行灵活使用. 一.Nginx知识简述Nginx是一个高性能的HTTP服务器和反向代理服务器,也是一个 IMAP/POP3/SM ...
- 【转】Linux下mysql操作
本文转自:http://www.cnblogs.com/xiaochaohuashengmi/archive/2011/10/18/2216279.html 1.linux下启动mysql的命令:my ...
- linux下mysql操作的命令
最近在学习mysql,还是只菜鸟,找到下面篇文章对初学者挺有用的,所以共享下 1.linux下启动mysql的命令: mysqladmin start /ect/init.d/mysql star ...
随机推荐
- YTU 2924: 文件操作--二进制文件读入
2924: 文件操作--二进制文件读入 时间限制: 1 Sec 内存限制: 128 MB 提交: 58 解决: 20 题目描述 现有100名学生的姓名(name).学号(num).英语(Engli ...
- MultiSelectComboBox(二)
1. MainWindow.xaml <Window x:Class="MultiSelectDemo.MainWindow" xmlns="htt ...
- 周赛-Colored Sticks 分类: 比赛 2015-08-02 09:33 7人阅读 评论(0) 收藏
Colored Sticks Time Limit: 5000MS Memory Limit: 128000K Total Submissions: 32423 Accepted: 8556 Desc ...
- Tiling 分类: POJ 2015-06-17 15:15 8人阅读 评论(0) 收藏
Tiling Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 8091 Accepted: 3918 Descriptio ...
- uva 816 Abbott的复仇
题目链接:https://uva.onlinejudge.org/external/8/816.pdf 紫书:P165 题意: 有一个最多包含9*9个交叉点的迷宫.输入起点.离开起点时的朝向和终点,求 ...
- Poj(2679),SPFA,邻接表(主流写法)
题目链接:http://poj.org/problem?id=3268 题意: 有编号为1-N的牛,它们之间存在一些单向的路径.给定一头牛的编号,其他牛要去拜访它并且拜访完之后要返回自己原来的位置,求 ...
- C# for和 foreach 的数组遍历 比较
刚学习程序,感觉写代码 很有意思,所以把自己的感悟写下来啦,第一次写博客,可能是菜鸟中的菜鸟 时间久了,相信就会写的很好哦! for和 foreach 的数组遍历 比较 很简单的程序,不解释啦! u ...
- 思考之一——PM(Project Manager)
摘自:http://blog.csdn.net/moreevan/article/details/6697806
- Hibernate中的PO
Hibernate中的PO PO就是持久化对象,它的作用就是完成持久化操作,即通过以面向对象的方式操作该对象对数据库中的数据执行增.删.改.查的操作. Hibernate是低侵入式的设计,完全采用Ja ...
- 在Window Embedded CE(Wince)下使用OpenNETCF进行路由表的开发
点击打开链接 背景 在开发3G项目的是时候,发现尽管3G网络连接已经建立成功了,但是数据不能发送成功,查明原因,由于路由表的问题,导致数据往ActiveSync连接的对端,也就是PC发送,而不是发送到 ...