您的位置:首页 > 编程语言

硬核!用这个工具看了i++和++i的汇编代码,小白也能明白它们的区别

2020-07-13 04:56 148 查看

大家好,我是阿汤哥。

 

++和++i的含义和区别:

 

它们的效果都是i自增。区别在于:i自增和计算整个表达式的值的先后顺序不一样。

 

前缀形式(++i):++在i的前面,所以i先自增,变成i+1,表达式的值式i+1。

 

后缀形式(i++):++在i的后面,所以i在赋值给表达式之后自增,表达式的值为i,之后i自增为i+1。

 

 

今天,我们来利用VC6.0的disassembly工具(一些其他的编程软件,比如CodeBlocks,也有这个功能),来看看 i++和 i--对应的汇编代码,你就更能明白它们的区别了。

 

先说个概念:

 

汇编语言:我们知道编程语言有很多种,有高级的编程语言(比如C、C++),也有更接近底层机器码的低级语言。

 

汇编语言就是这样的一种低级语言,它介于高级语言和机器语言(二进制代码)之间。

 

高级语言的代码,通常可以写的很简洁,但是它对应的汇编语言代码可能会有多个语句。

 

我们可以理解为,汇编是对高级语言代码的一个拆分和细化。

 

看汇编语言的代码,你更能明白底层的指令是怎么运行的。

 

举个例子:

 

int i =5;

 

这行C语言代码对应的汇编代码的形式为:

 

mov         dword ptr [ebp-4], 5  

 

其中mov是一个汇编指令,作用是数据传送,把一个数据传送到一个目标地址。

 

dword ptr [ebp-4]  :这个是i的地址  (其中dword,全程是double word,双字。也就是四个字节;ebp)

 

5:就i是要传送的数据。

 

这行代码的含义就是把5传送到地址dword ptr [ebp-4]里。

 

再说一个汇编里的指令add,顾名思义,这是加法指令。

 

接下来,我们看看如何在vc6.0里查看C代码对应的汇编代码:

 

第一步,把鼠标放到代码任意一行,比如"int a =0"这行。然后点击图中手形图标,插入一个断点。

 

 

第二步,点击下面图中的图标。

 

 

第三步,菜单栏->View -> Debug Windows -> Disassembly

 

就能看到每行C代码对应的汇编代码了。截图如下:

 

第一列的0040D708这个不用管,这个是内存地址编号。

 

7: 8: ... 11:这几个是C代码在源文件中的行数。

 

我们着重来比较下int a = ++i和 int a = i++汇编代码的差异。

 

我们来看下每行的含义:(你大致知道个意思,不用深究汇编的代码)

 

初始化变量i和a:

 

[code]7:        int i = 5;
//把5传送到内存地址dword ptr [ebp-4](这是i的内存地址)中
  mov         dword ptr [ebp-4],5
9:        int a = 0;
//把0传送到内存地址dword ptr [ebp-8](这是a的内存地址)中
   mov         dword ptr [ebp-8],0

 

 

语句:a = ++1

 

[code]11:       a = ++i;
//(1)首先把i所在地址dword ptr [ebp-4]的内容(5)放进累加器eax
   mov         eax,dword ptr [ebp-4]
//(2)执行add执行,累加器eax中的数加上1(变为6)
   add         eax,1
//(3)把加1后的累加器eax中的数(6),再传送给i的地址dword ptr [ebp-4]
   mov         dword ptr [ebp-4],eax
//(4)把i所在地址dword ptr [ebp-4]的数(6)传送给ecx寄存器
   mov         ecx,dword ptr [ebp-4]
//(5)把ecx寄存器中的传送给a所在地址dword ptr [ebp-8]
   mov         dword ptr [ebp-8],ecx

 

 

可以看出,它是i先自增,然后把自增后的i的值赋给a;

 

语句 a = i++

 

[code]13:       a = i++;
//(1)把i所在地址dword ptr [ebp-4]的内容(6)放进edx寄存器
   mov         edx,dword ptr [ebp-4]
//(2)把edx寄存器中的数(6)传送给a所在地址dword ptr [ebp-8]
   mov         dword ptr [ebp-8],edx
//(3)把i所在地址dword ptr [ebp-4]的内容(6)放进累加器edx
   mov         eax,dword ptr [ebp-4]
//(4)执行add(加法)指令,累加器中的数加1,变为7
   add         eax,1
//(5)把累加器eax中的数(7)传送给i所在内存地址dword ptr [ebp-4]
   mov         dword ptr [ebp-4],eax

 

 

可以看出,先把i的值赋给a,然后i再自增。

 

 

看了的汇编代码,相信大家更能明白++i和i++的区别了。

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐