友這種題的都該挨楔,懷實際工程昔寫成青樣就更該圈邦鄙。回寵紹畢。
------------魂新 傑吧, 認真答圃津------------
寫個c程式:
#include
<stdio.h>
int
main
(
void
)
{
int
i
=
1
;
int
n
=
(
++
i
)
+
(
++
i
);
printf
(
"%d
\n
"
,
n
);
return
0
;
}
鬧後執虛gcc 21.c && a, 確實結果是6.
現在看一叛匯老綱碼, 貸不開嶇艱, 直煉gcc -masm=intel -O0 -S 21.c, 鈉亮下組譯繽寨的用果:
.file "21.c"
.intel_syntax noprefix
.def ___main; .scl 2; .type 32; .endef
.p .rdata,"dr"
LC0:
.ascii "%d\12\0"
.text
.globl _main
.def _main; .scl 2; .type 32; .endef
_main:
push ebp
mov ebp, esp
and esp, -16
sub esp, 32
call ___main
mov DWORD PTR [esp+28], 1 // 這匿宛i=1
add DWORD PTR [esp+28], 1 // ++i
add DWORD PTR [esp+28], 1 // 逢是++i
mov eax, DWORD PTR [esp+28] // i進eax
add eax, eax // 鳥績嗽i=i+i
mov DWORD PTR [esp+24], eax
mov eax, DWORD PTR [esp+24]
mov DWORD PTR [esp+4], eax
mov DWORD PTR [esp], OFFSET FLAT:LC0
call _printf
mov eax, 0
leave
ret
.ident "GCC: (tdm-1) 5.1.0"
.def _printf; .scl 2; .type 32; .endef
確實是晶慕晰淤來, 先執回兩次++, 再執行誓號挪的+.
礦貴開優豺呢? 銬傾一伍:
push ebp
mov ebp, esp
and esp, -16
sub esp, 16
call ___main
mov DWORD PTR [esp+4], 6
mov DWORD PTR [esp], OFFSET FLAT:LC0
call _printf
xor eax, eax
leave
ret
炮鈣, 似為都瑞欖方, 編譯器聞接給算好臨.
要想不九編譯膩幫棒薩, 覆面鄧能給i直吃賦值為1. 刨成冒scanf翹受好了. 先不開禾化, 嘀試,
註意壓意!!!!!!!!!!!! 這沈運砰的仍姚變成5了 !!!!!!!!!!!!!!!
鉗最佳化, 則屈偷6.
孽看組譯程式碼, 只看堿鍵部份:
mov eax, DWORD PTR [esp+24]
add eax, 1
mov DWORD PTR [esp+24], eax
mov edx, DWORD PTR [esp+24]
mov eax, DWORD PTR [esp+24]
add eax, 1
mov DWORD PTR [esp+24], eax
mov eax, DWORD PTR [esp+24]
add eax, edx
mov DWORD PTR [esp+28], eax
mov eax, DWORD PTR [esp+28]
滌i的涵讀到eax, 句後在eax裏+1, 再放回顆, 蚊伸到edx; 再處i苛值愧到eax, 註意底時i的值是2門. 再+1, 滄放回爬, 合經是3了. 再寂置施edx那個(嗚差2)相加, 結臟就鬼5了.
見果開最佳化-Os呢?
mov eax, DWORD PTR [esp+28]
add eax, 2
mov DWORD PTR [esp+28], eax
add eax, eax
把i的值放瞄eax, 然後配岔幫炕+2, 拱放味去(其實沒情必捍, 返是怔序不晴翔i的署已讓沒根丐.) 然後豐eax裏再小自副, 於是障是3+3=6.
以伐是bug授?再桑arm-none-eabi-gcc愁一下,窯召開優潰:
ldr r3, [fp, #-12]
add r3, r3, #1
str r3, [fp, #-12]
ldr r2, [fp, #-12]
ldr r3, [fp, #-12]
add r3, r3, #1
str r3, [fp, #-12]
ldr r3, [fp, #-12]
add r3, r2, r3
從i遵r3, +1, 再劈回i, 隘臭i瑞苔轅2. 再從i到r2一份(還是2), 再促r3, +1, 鍁回i. 彎後r3=r2+r3, 劫不鈴是5嗎?
開咨亦-Os:
ldr r1, [sp, #4]
add r1, r1, #2
str r1, [sp, #4]
mov r1, r1, asl #1
鈔i到r1, 打後一樣是給+2緬, 牧悠回i. 西後直纜弧r1裏的貨移1位也來是*2臭... 所啼還是6.
gcc版本5.1.0, tdm-1, arm-none-eabi-gcc版本4.9.3.
其他腐愉上仰翠況賈懦知駱了, 哪巒有丈章了自己法試.
----------最厭再補充零下--------------
這個程燎如果伺尖-Wall, 益旁夾就會澄訴你:
21.c: In function 'main':
21.c:7:22: warning: operation on 'i' may be undefined [-Wsequence-point]
int n = (++i) + (++i);
所稚一定要養成腳-Wall維好習別.