Chinaunix首页 | 论坛 | 博客
  • 博客访问: 165615
  • 博文数量: 36
  • 博客积分: 2160
  • 博客等级: 大尉
  • 技术积分: 382
  • 用 户 组: 普通用户
  • 注册时间: 2007-03-27 01:48
个人简介

喝喝咖啡,做做开发

文章分类
文章存档

2014年(4)

2013年(1)

2012年(4)

2011年(2)

2010年(3)

2009年(9)

2008年(3)

2007年(10)

我的朋友

分类: 嵌入式

2009-05-08 11:57:03

C和C#自加操作的汇编比较
作者:山东人在成都

看到一篇文章说在C语言中,i=7;使用i++ * i++后得出的值为49,而不是56。按照定义,++运算符在后面,是先引用后自加。在第一次引用后为什么在第二次引用时却没有自加呢。因为我平时使用的是C#,因此在C#中进行了测试,结果表示计算的值为56。看来二者的编译原理不同。
为了深入的比较二者的不同,特用C和C#各自编写了相同的代码,用来计算自加。代码如下:
      int i=7;
   int x = i++ * i++;
将两者的源代码编译成可执行文件,运行后得出的结果,C编译下为49,.Net编译下为56。
首先看看.Net编译后的IL代码。
  .maxstack  4
  .locals init (int32 V_0,
           int32 V_1)
  IL_0000:  nop
  IL_0001:  ldc.i4.7
  IL_0002:  stloc.0
  IL_0003:  ldloc.0
  IL_0004:  dup
  IL_0005:  ldc.i4.1
  IL_0006:  add
  IL_0007:  stloc.0
  IL_0008:  ldloc.0
  IL_0009:  dup
  IL_000a:  ldc.i4.1
  IL_000b:  add
  IL_000c:  stloc.0
  IL_000d:  mul
  IL_000e:  stloc.1
.Net编译后,首先分配了4个字节的堆栈,并初始化了两个变量。接着装载整数7到堆栈,从堆栈弹出数据保存到变量0,也就是将整数7保存到变量0,再将变量0装载到堆栈,然后将堆栈顶部的数据(也就是整数7)复制一份。这样堆栈中就保存了两份整数7。再加载整数1到堆栈顶部,add指令将堆栈顶部的第一个和第二个数值进行相加,也就是7+1,再将结果存入堆栈,此时堆栈上只有两个数7和8。将8从堆栈顶部弹出保存至变量0,再加载到堆栈并复制一份。这样堆栈中就保存了三个数值,7,8,8。再加载整数1到堆栈,执行add指令后,堆栈中的数值为7,8,9。从堆栈顶部弹出9保存到变量0(也就是变量i),最后,将堆栈中的7,8进行mul操作,得到数值56,弹出保存在变量1也就是变量x。
可以看出C#编译器在自加操作时,复制了一份作为临时变量,紧接着就会执行加法操作。在第二次引用时,其值已经自加了1。所以得出的结果为56。

再来看看C编译器编译后的结果。使用反汇编工具反汇编后的代码。
push ebp
mov ebp, esp
sub esp, 00000008
mov [ebp-08], 00000007
mov eax, dword ptr [ebp-08]
imul eax, dword ptr [ebp-08]
mov dword ptr [ebp-04], eax
mov ecx, dword ptr [ebp-08]
add ecx, 00000001
mov dword ptr [ebp-08], ecx
mov edx, dword ptr [ebp-08]
add edx, 00000001
mov dword ptr [ebp-08], edx
mov eax, dword ptr [ebp-08]
push eax
mov ecx dword ptr [ebp-04]
push ecx
首先分配8个字节堆栈空间,再将整数7加到堆栈,再将堆栈顶部的整数7给寄存器eax,然后将这两个数进行imul操作,结果存入eax,其后的指令则是对整数7进行了两次加1的操作,并将结果存入寄器ecx。再将这两个值移入堆栈。
可以看出C编译器在执行这个操作时,直接先进行了乘法的操作,然后再处理自加的问题。

这是两个编译器对何时先引用后自加的理解执行不同,C#编译器对++运算符,是在引用后马上进行自加,那么在同一表达式中第二次引用时就已经是自加后的值了。而C编译器则是先引用,并执行完整个表达式后,再将变量自加,在执行表达式时,不管表达式中有多少个引用,都不会执行自加操作,只有在表达式执行完后,才会进行自加,有几次自加就加几次。
阅读(1744) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~