(编程语言中)后置++(即i++),分别通过汇编和字节码分析其在vs2012 C++和java中区别
2013-09-29 16:18
429 查看
微软的一道面试题(2014年校招)
代码:
int i=0;
i+=i>0?i++:i--;
问i等于多少?
在vs2012 C++中等于 -1,而在java中i最终等于0。
下面看看一些关于后置++的底层代码
C++代码:
int i=0;
int b=0;
b=i++;
结果:b=0 i=1
汇编代码:
int i=0;
01326D3E mov dword ptr [i],0 // i<- 0
int b=0;
01326D45 mov dword ptr [b],0 // b<- 0
b=i++;
01326D4C mov eax,dword ptr [i] //
eax<- i
01326D4F mov dword ptr [b],eax // b<- eax
01326D52 mov ecx,dword ptr [i] // ecx<- i
01326D55 add ecx,1 //
ecx<- ecx+1
01326D58 mov dword ptr [i],ecx //
i<- ecx
由汇编代码可知,vs2012 C++先将 b<- i,然后i<- i+1.
********************************************************************
C++代码:
int i=0;
int b=0;
b+=i++;
结果:b=0 i=1
汇编代码:
int i=0;
00106D3E mov dword ptr [i],0 // i<- 0
int b=0;
00106D45 mov dword ptr [b],0 //
b<- 0
b+=i++;
00106D4C mov eax,dword ptr [b] //
eax<- b
00106D4F add eax,dword ptr [i] //eax <- eax+i
00106D52 mov dword ptr [b],eax //
b<- eax
00106D55 mov ecx,dword ptr [i] // ecx<- i
00106D58 add ecx,1 //
ecx<-ecx+1
00106D5B mov dword ptr [i],ecx //
i<- ecx
由汇编代码可知,vs2012 C++先将 b<- b+i,然后i<- i+1.
****************************************************************************
C++代码:
int i=0;
int b=0;
b+=i>0?i++:i--;
结果:b=0 i=-1
汇编代码:
int i=0;
01166D3E mov dword ptr [i],0 //i<- 0
int b=0;
01166D45 mov dword ptr [b],0 //b<- 0
b+=i>0?i++:i--;
01166D4C cmp dword ptr [i],0 //cmp i , 0
01166D50 jle main+46h (01166D66h) //如果小于,转 main+46h (01166D66h)
01166D52 mov eax,dword ptr [i] //eax<- i
01166D55 mov dword ptr [ebp-0DCh],eax // temp <- eax (temp 临时变量)
01166D5B mov ecx,dword ptr [i] // ecx<- i
01166D5E add ecx,1 // ecx<- ecx+1
01166D61 mov dword ptr [i],ecx // i<- ecx
01166D64 jmp main+58h (01166D78h) //转main+58h (01166D78h)
01166D66 mov edx,dword ptr [i] // edx<- i
01166D69 mov dword ptr [ebp-0DCh],edx //temp<- edx
01166D6F mov eax,dword ptr [i] //eax<- i
01166D72 sub eax,1 //eax<- eax-1
01166D75 mov dword ptr [i],eax //i<- eax
01166D78 mov ecx,dword ptr [b]
// ecx<- b
01166D7B add ecx,dword ptr [ebp-0DCh] // ecx<- ecx +temp
01166D81 mov dword ptr [b],ecx //b<- ecx
*****************************************************
C++代码:
int i=0;
i+=i>0?i++:i--;
结果:i=-1
汇编代码:
int i=0;
00C36D3E mov dword ptr [i],0 //i<- 0
i+=i>0?i++:i--;
00C36D45 cmp dword ptr [i],0 //cmp i , 0
00C36D49 jle main+3Fh (0C36D5Fh) //如果小于,转 main+3Fh (0C36D5Fh)
00C36D4B mov eax,dword ptr [i] //eax<- i
00C36D4E mov dword ptr [ebp-0D0h],eax // temp <- eax (temp 临时变量)
00C36D54 mov ecx,dword ptr [i] // ecx<- i
00C36D57 add ecx,1
// ecx<- ecx+1
00C36D5A mov dword ptr [i],ecx // i<- ecx
00C36D5D jmp main+51h (0C36D71h) //转main+51h (0C36D71h)
00C36D5F mov edx,dword ptr [i] //edx<- i
00C36D62 mov dword ptr [ebp-0D0h],edx //temp<- edx
00C36D68 mov eax,dword ptr [i] //eax<- i
00C36D6B sub eax,1
//eax<- eax-1
00C36D6E mov dword ptr [i],eax // i<- eax
00C36D71 mov ecx,dword ptr [i] // ecx<- i
00C36D74 add ecx,dword ptr [ebp-0D0h] // ecx<- ecx +temp
00C36D7A mov dword ptr [i],ecx
// i<- ecx
***************************************************************
java代码:
int i=0;
i+=i>0?i++:i--;
结果:i=0
java字节码:
0: iconst_0 //stack中存入一个int常量0
1: istore_1 //把它(从栈中弹出)赋值给第一个变量,即我们的i
2: iload_1 //把i入栈
3: iload_1 //把i入栈
4: ifle 14 //如果 栈顶元素小于0,转14
7: iload_1
//把i入栈
8: iinc 1, 1
//i(变量表中的i,不是栈中的i)自加1
11: goto 18 //转18
14: iload_1 //把变量表中的i入栈
15: iinc 1, -1 //把变量表中的i自减1
18: iadd //把栈顶两个元素相加
19: istore_1 //把栈顶元素存入到 i(变量表中的i)
代码:
int i=0;
i+=i>0?i++:i--;
问i等于多少?
在vs2012 C++中等于 -1,而在java中i最终等于0。
下面看看一些关于后置++的底层代码
C++代码:
int i=0;
int b=0;
b=i++;
结果:b=0 i=1
汇编代码:
int i=0;
01326D3E mov dword ptr [i],0 // i<- 0
int b=0;
01326D45 mov dword ptr [b],0 // b<- 0
b=i++;
01326D4C mov eax,dword ptr [i] //
eax<- i
01326D4F mov dword ptr [b],eax // b<- eax
01326D52 mov ecx,dword ptr [i] // ecx<- i
01326D55 add ecx,1 //
ecx<- ecx+1
01326D58 mov dword ptr [i],ecx //
i<- ecx
由汇编代码可知,vs2012 C++先将 b<- i,然后i<- i+1.
********************************************************************
C++代码:
int i=0;
int b=0;
b+=i++;
结果:b=0 i=1
汇编代码:
int i=0;
00106D3E mov dword ptr [i],0 // i<- 0
int b=0;
00106D45 mov dword ptr [b],0 //
b<- 0
b+=i++;
00106D4C mov eax,dword ptr [b] //
eax<- b
00106D4F add eax,dword ptr [i] //eax <- eax+i
00106D52 mov dword ptr [b],eax //
b<- eax
00106D55 mov ecx,dword ptr [i] // ecx<- i
00106D58 add ecx,1 //
ecx<-ecx+1
00106D5B mov dword ptr [i],ecx //
i<- ecx
由汇编代码可知,vs2012 C++先将 b<- b+i,然后i<- i+1.
****************************************************************************
C++代码:
int i=0;
int b=0;
b+=i>0?i++:i--;
结果:b=0 i=-1
汇编代码:
int i=0;
01166D3E mov dword ptr [i],0 //i<- 0
int b=0;
01166D45 mov dword ptr [b],0 //b<- 0
b+=i>0?i++:i--;
01166D4C cmp dword ptr [i],0 //cmp i , 0
01166D50 jle main+46h (01166D66h) //如果小于,转 main+46h (01166D66h)
01166D52 mov eax,dword ptr [i] //eax<- i
01166D55 mov dword ptr [ebp-0DCh],eax // temp <- eax (temp 临时变量)
01166D5B mov ecx,dword ptr [i] // ecx<- i
01166D5E add ecx,1 // ecx<- ecx+1
01166D61 mov dword ptr [i],ecx // i<- ecx
01166D64 jmp main+58h (01166D78h) //转main+58h (01166D78h)
01166D66 mov edx,dword ptr [i] // edx<- i
01166D69 mov dword ptr [ebp-0DCh],edx //temp<- edx
01166D6F mov eax,dword ptr [i] //eax<- i
01166D72 sub eax,1 //eax<- eax-1
01166D75 mov dword ptr [i],eax //i<- eax
01166D78 mov ecx,dword ptr [b]
// ecx<- b
01166D7B add ecx,dword ptr [ebp-0DCh] // ecx<- ecx +temp
01166D81 mov dword ptr [b],ecx //b<- ecx
*****************************************************
C++代码:
int i=0;
i+=i>0?i++:i--;
结果:i=-1
汇编代码:
int i=0;
00C36D3E mov dword ptr [i],0 //i<- 0
i+=i>0?i++:i--;
00C36D45 cmp dword ptr [i],0 //cmp i , 0
00C36D49 jle main+3Fh (0C36D5Fh) //如果小于,转 main+3Fh (0C36D5Fh)
00C36D4B mov eax,dword ptr [i] //eax<- i
00C36D4E mov dword ptr [ebp-0D0h],eax // temp <- eax (temp 临时变量)
00C36D54 mov ecx,dword ptr [i] // ecx<- i
00C36D57 add ecx,1
// ecx<- ecx+1
00C36D5A mov dword ptr [i],ecx // i<- ecx
00C36D5D jmp main+51h (0C36D71h) //转main+51h (0C36D71h)
00C36D5F mov edx,dword ptr [i] //edx<- i
00C36D62 mov dword ptr [ebp-0D0h],edx //temp<- edx
00C36D68 mov eax,dword ptr [i] //eax<- i
00C36D6B sub eax,1
//eax<- eax-1
00C36D6E mov dword ptr [i],eax // i<- eax
00C36D71 mov ecx,dword ptr [i] // ecx<- i
00C36D74 add ecx,dword ptr [ebp-0D0h] // ecx<- ecx +temp
00C36D7A mov dword ptr [i],ecx
// i<- ecx
***************************************************************
java代码:
int i=0;
i+=i>0?i++:i--;
结果:i=0
java字节码:
0: iconst_0 //stack中存入一个int常量0
1: istore_1 //把它(从栈中弹出)赋值给第一个变量,即我们的i
2: iload_1 //把i入栈
3: iload_1 //把i入栈
4: ifle 14 //如果 栈顶元素小于0,转14
7: iload_1
//把i入栈
8: iinc 1, 1
//i(变量表中的i,不是栈中的i)自加1
11: goto 18 //转18
14: iload_1 //把变量表中的i入栈
15: iinc 1, -1 //把变量表中的i自减1
18: iadd //把栈顶两个元素相加
19: istore_1 //把栈顶元素存入到 i(变量表中的i)
相关文章推荐
- 虚函数与纯虚函数(C++与Java虚函数的区别)的深入分析
- Java和C++通过new创建的对象有何区别?
- 编程语言拟人化(1):Java、C++、Python、Ruby、PHP、C#、JS的区别
- C#,Java,c++的特点区别,C#分别从c++和java中吸取了他们那些优点?
- 面试引发的high level abstration of OO language books named "Objects Unencapsulated: Java, Eiffel, and C++?" --正反全面分析编程语言
- 通过字节码深入分析java的枚举类型enum
- c++ 内存分配过程(通过汇编,寄存器和Memory分析)
- 通过汇编代码分析C++的动态联编机制
- 通过字节码分析java中的switch语句
- C++中通过指针,引用方式做返回值的汇编代码分析
- 面向过程 面向对象的区别以及C++与Java的区别
- 从Java源码的角度来分析HashMap与HashTable的区别
- 通过汇编理解返回char p []和char *p 中P的区别
- Java--JAVA和C++区别(一)
- C、C++、java的区别
- C++中重载、重写(覆盖)和隐藏的区别实例分析
- 算法设计、分析与实现 从入门到精通 C、C++和Java 这本书的堆实现85页C++语言实现有问题
- JAVA通过JNI调用C++程序实践
- C++和JAVA的区别
- java学习(12)对象数组初始化 java与C++的区别