|
发表于 2021-1-14 18:09:18
|
显示全部楼层
本楼为最佳答案
本帖最后由 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 的来历。 |
|