int i = 0;
i=i++;
在c语言和java中上述两句话的运行结果是不同的,那么到底是为什么呢?
这原因可能能从大量的语法规范中获得最终的解答,但是能不能更直接地得出原因呢?
答案是肯定的,其实造成这种原因的根本就是我们并没有完全确定i=i++这句话的执行真实的情况.
好了,下面通过反汇编给出解答.
首先,在c语言中这两句话反汇编的结果如下:
mov dword ptr [ebp-4],0 ;这句话即为int i = 0
mov eax,dword ptr [ebp-4] ;将i的值给寄存器eax
mov dword ptr [ebp-4],eax ;将寄存器的值给i
mov ecx,dword ptr [ebp-4] ;将i的值给寄存器ecx
add ecx,1 ;将寄存器ecx的值加1
mov dword ptr [ebp-4],ecx ;将ecx的值给ax
有汇编基础的可以很容易得到答案. i最终的值是1.
下面是java中这两句话的反汇编结果:
iconst_0 ;0入栈
istore_1 ;将栈顶int类型值保存到局部变量1中,至此完成int i = 0
iload_1 ;将局部变量1的int类型值入栈
iinc 1,1 ;局部变量1加1,此时i变为1
istore_1 ;将栈顶int类型值保存到局部变量1中,此时i又变回了0
从上面的注释中大家可以很容易看出将i自增是在赋值语句之前的,所以i=i++;这句话的实际执行流程是先将i的值压入栈,在将i的值增加1,最后把刚才压入栈的值弹出保存到i中.
最后谈一点:java的指令流是一种基于栈的指令集架构,指令流中的大部分都是零地址指令,依赖于操作数栈进行工作.与之相对的另一套常用的架构是基于寄存器的指令集,最典型的就是我们熟悉的x86指令集.