猜下结果:
PHP:
<?php
$i = 1;
echo (++$i) + (++$i) + (++$i);
?>
C:
#include
int main()
{
int i = 1;
printf("%d", (++i) + (++i) +(++i));
return 0;
}
这个结果肯定会让大家感到一点意外,两个语言运算的结果是不一样的。
PHP 为:9 ( 即:2+3+4,PHP总是这么可爱,所想即所得)
C 为: 10 (这个结果让我感觉很意外,反汇编跟了下)
部分代码我贴出来:
0040102C |. B9 12000000 MOV ECX,12
00401031 |. B8 CCCCCCCC MOV EAX,CCCCCCCC
00401036 |. F3:AB REP STOS DWORD PTR ES:[EDI]
00401038 |. C745 FC 01000>MOV DWORD PTR SS:[EBP-4],1 ;i = 1
0040103F |. 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4] ;ax = i;
00401042 |. 83C0 01 ADD EAX,1 ;ax++; ax = 2;
00401045 |. 8945 FC MOV DWORD PTR SS:[EBP-4],EAX ;i = 2;
00401048 |. 8B4D FC MOV ECX,DWORD PTR SS:[EBP-4] ;cx = 2;
0040104B |. 83C1 01 ADD ECX,1 ;cx++; cx = 3;
0040104E |. 894D FC MOV DWORD PTR SS:[EBP-4],ECX ;i = cx;
00401051 |. 8B55 FC MOV EDX,DWORD PTR SS:[EBP-4] ;dx = i;
00401054 |. 0355 FC ADD EDX,DWORD PTR SS:[EBP-4] ;dx = dx+i; dx = 3+3 = 6;
00401057 |. 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4] ;ax = i; ax = 3;
0040105A |. 83C0 01 ADD EAX,1 ;ax++; ax=4
0040105D |. 8945 FC MOV DWORD PTR SS:[EBP-4],EAX ;i = ax;
00401060 |. 0355 FC ADD EDX,DWORD PTR SS:[EBP-4] ;dx=dx+i; dx=6+4;
00401063 |. 52 PUSH EDX ;dx 为第一个参数,值为: 10
00401064 |. 68 1C304200 PUSH stack_ov.0042301C ; |Arg1 = 0042301C ASCII "%d"
00401069 |. E8 02040000 CALL stack_ov.00401470 ; \stack_ov.00401470
通过观察发现,C通过寄存器AX,CX,DX 作为中转站,运算的过程为:3+3+4
也就是说c对表达式的支持为两个一条,
(++i) + (++i) + (++i)
<==>
(++i) + (++i)
(++i) + i
所以我们推测再加一个++i 的结果是
(++i) + (++i)
(++i) + i
(++i) + i
也就是 3+3+4+5 = 15
经过实际验证,我们的猜想对了。
|