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 ...
随机推荐
- poj3372 Candy Distribution
可以证明: f(k) = k *(k - 1)/ 2 (1 ≤ k ≤ n)是n的完全剩余系当且仅当n = 2 ^ t. http://poj.org/problem?id=3372
- Moo University - Financial Aid
Moo University - Financial Aid Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 6020 Accep ...
- C#获得枚举类型的长度
enum MyEnum { Value1, Value2, } class Program { static void Main(string[] args) { var e = new MyEnum ...
- 操作SQLite的dbhelper
操作SQLite的dbhelper public class DbHelper { string connStr = @"Data Source=" + System.Enviro ...
- 数字证书私钥sign及验证
package com.epay.bank.test.encrypt; import java.io.FileInputStream; import java.security.KeyStore; i ...
- java-以月为单位,得到一年中某一个月份的范围
简单说:得到某一月份的第一天,第一小时,第一分钟,第一秒和某一月份的最后一天,最后一小时,最后一分钟,最后一秒. 实现: //月初 private Date getBeginTimeOfMonth(i ...
- Swift语法总结补充(一)
Swift基础语法学习总结Swift高级语法学习总结Swift语法总结补充(一) 1. 可选类型是一种类型,String?就是Optional<String>,所以函数参数也可以声明为它2 ...
- FreeSWITCH一些需求应对
一.用户号码组 听到这个名词的时候,心中还挺迷茫,需求如下: 一个用户分配号码为800,但是这个用户有一部座机,两部手机:有人拨打800这个号码时,这个用户的所有关联终端都要振铃. 其实就是用户号码多 ...
- Limiting To Select Only 5 Check Boxes Out Of Ten In Oracle Forms
Suppose you want to give an option to user to select only 5 check boxes from given any number of che ...
- Myeclipse 10.7 android(安卓) 开发环境搭建
1 下载并安装JDK,并且设置环境变量 2 下载安装 installer_r24.3.4-windows.exe (Android SDK Manager) 3 使用 Android SDK Mana ...