本帖最后由 jackz007 于 2021-1-14 18:39 编辑
使用 gcc 编译这个代码#include <stdio.h>
int main(void)
{
int j = 5 , q ;
q = (++ j) + (++ j) + (++ j) ;
printf("%d\n" , q) ;
}
运行结果是 22,非常的怪异,为了搞清楚这个值的来历,我用 OD 对可执行程序的反汇编代码进行了静态分析00401360 /$ 55 push ebp
00401361 |. 89E5 mov ebp, esp
00401363 |. 83E4 F0 and esp, 0xFFFFFFF0
00401366 |. 83EC 20 sub esp, 0x20
00401369 |. E8 A2050000 call 00401910
0040136E |. C74424 1C 05000000 mov dword ptr [esp+0x1C], 0x5 ; j = 5
00401376 |. 834424 1C 01 add dword ptr [esp+0x1C], 0x1 ; j = j + 1 = 6
0040137B |. 834424 1C 01 add dword ptr [esp+0x1C], 0x1 ; j = j + 1 = 7
00401380 |. 8B4424 1C mov eax, dword ptr [esp+0x1C] ;
00401384 |. 8D1400 lea edx, dword ptr [eax+eax] ; i = j + j = 14
00401387 |. 834424 1C 01 add dword ptr [esp+0x1C], 0x1 ; j = j + 1 = 8
0040138C |. 8B4424 1C mov eax, dword ptr [esp+0x1C] ;
00401390 |. 01D0 add eax, edx ; q = j + i = 8 + 14 = 22
00401392 |. 894424 18 mov dword ptr [esp+0x18], eax ; |
00401396 |. 8B4424 18 mov eax, dword ptr [esp+0x18] ; |
0040139A |. 894424 04 mov dword ptr [esp+0x4], eax ; |
0040139E |. C70424 00504000 mov dword ptr [esp], 00405000 ; |ASCII "%d\n"
004013A5 |. E8 66270000 call <jmp.&msvcrt.printf> ; \printf
004013AA |. B8 00000000 mov eax, 0x0
004013AF |. C9 leave
004013B0 \. C3 retn
上面的汇编代码我已经做了注释。
我们看到,代码执行细节用 C 语言描述过程是这样的: int i , j = 5 , q ;
j ++ ;
j ++ ;
i = j + j ;
j ++ ;
q = j + i ;
这就是 22 的来历。 |