我的测试表明,第二个版本比前一个版本短了 4 条指令,但优化后的版本长度相同:
我测试
代码:
main(a) {
if(a == 10)
puts("10");
else if(a == 20)
puts("20");
else if(a < 100)
puts("yes");
}
驳斥:
0x00000000004004dc <+0>: push rbp
0x00000000004004dd <+1>: mov rbp,rsp
0x00000000004004e0 <+4>: sub rsp,0x10
0x00000000004004e4 <+8>: mov DWORD PTR [rbp-0x4],edi
0x00000000004004e7 <+11>: cmp DWORD PTR [rbp-0x4],0xa
0x00000000004004eb <+15>: jne 0x4004f9 <main+29>
0x00000000004004ed <+17>: mov edi,0x4005c4
0x00000000004004f2 <+22>: call 0x4003b0 <puts@plt>
0x00000000004004f7 <+27>: jmp 0x40051b <main+63>
0x00000000004004f9 <+29>: cmp DWORD PTR [rbp-0x4],0x14
0x00000000004004fd <+33>: jne 0x40050b <main+47>
0x00000000004004ff <+35>: mov edi,0x4005c7
0x0000000000400504 <+40>: call 0x4003b0 <puts@plt>
0x0000000000400509 <+45>: jmp 0x40051b <main+63>
0x000000000040050b <+47>: cmp DWORD PTR [rbp-0x4],0x63
0x000000000040050f <+51>: jg 0x40051b <main+63>
0x0000000000400511 <+53>: mov edi,0x4005ca
0x0000000000400516 <+58>: call 0x4003b0 <puts@plt>
0x000000000040051b <+63>: leave
0x000000000040051c <+64>: ret
优化:
0x00000000004004dc <+0>: sub rsp,0x8
0x00000000004004e0 <+4>: cmp edi,0xa
0x00000000004004e3 <+7>: jne 0x4004f1 <main+21>
0x00000000004004e5 <+9>: mov edi,0x4005c4
0x00000000004004ea <+14>: call 0x4003b0 <puts@plt>
0x00000000004004ef <+19>: jmp 0x400511 <main+53>
0x00000000004004f1 <+21>: cmp edi,0x14
0x00000000004004f4 <+24>: jne 0x400502 <main+38>
0x00000000004004f6 <+26>: mov edi,0x4005c7
0x00000000004004fb <+31>: call 0x4003b0 <puts@plt>
0x0000000000400500 <+36>: jmp 0x400511 <main+53>
0x0000000000400502 <+38>: cmp edi,0x63
0x0000000000400505 <+41>: jg 0x400511 <main+53>
0x0000000000400507 <+43>: mov edi,0x4005ca
0x000000000040050c <+48>: call 0x4003b0 <puts@plt>
0x0000000000400511 <+53>: add rsp,0x8
0x0000000000400515 <+57>: ret
二、测试
代码:
main(a) {
if(a == 10)
puts("10");
if(a == 20)
puts("20");
if(a < 100)
puts("yes");
}
驳斥:
0x00000000004004dc <+0>: push rbp
0x00000000004004dd <+1>: mov rbp,rsp
0x00000000004004e0 <+4>: sub rsp,0x10
0x00000000004004e4 <+8>: mov DWORD PTR [rbp-0x4],edi
0x00000000004004e7 <+11>: cmp DWORD PTR [rbp-0x4],0xa
0x00000000004004eb <+15>: jne 0x4004f7 <main+27>
0x00000000004004ed <+17>: mov edi,0x4005c4
0x00000000004004f2 <+22>: call 0x4003b0 <puts@plt>
0x00000000004004f7 <+27>: cmp DWORD PTR [rbp-0x4],0x14
0x00000000004004fb <+31>: jne 0x400507 <main+43>
0x00000000004004fd <+33>: mov edi,0x4005c7
0x0000000000400502 <+38>: call 0x4003b0 <puts@plt>
0x0000000000400507 <+43>: cmp DWORD PTR [rbp-0x4],0x63
0x000000000040050b <+47>: jg 0x400517 <main+59>
0x000000000040050d <+49>: mov edi,0x4005ca
0x0000000000400512 <+54>: call 0x4003b0 <puts@plt>
0x0000000000400517 <+59>: leave
0x0000000000400518 <+60>: ret
优化:
0x00000000004004dc <+0>: sub rsp,0x8
0x00000000004004e0 <+4>: cmp edi,0xa
0x00000000004004e3 <+7>: jne 0x4004f1 <main+21>
0x00000000004004e5 <+9>: mov edi,0x4005c4
0x00000000004004ea <+14>: call 0x4003b0 <puts@plt>
0x00000000004004ef <+19>: jmp 0x400507 <main+43>
0x00000000004004f1 <+21>: cmp edi,0x14
0x00000000004004f4 <+24>: jne 0x400502 <main+38>
0x00000000004004f6 <+26>: mov edi,0x4005c7
0x00000000004004fb <+31>: call 0x4003b0 <puts@plt>
0x0000000000400500 <+36>: jmp 0x400507 <main+43>
0x0000000000400502 <+38>: cmp edi,0x63
0x0000000000400505 <+41>: jg 0x400511 <main+53>
0x0000000000400507 <+43>: mov edi,0x4005ca
0x000000000040050c <+48>: call 0x4003b0 <puts@plt>
0x0000000000400511 <+53>: add rsp,0x8
0x0000000000400515 <+57>: ret
展位测试由 gcc 版本 4.7.0 20120324 (prerelease) (GCC) 在 Linux 3.2.14-1-ARCH x86_64 Intel(R) Core(TM) i5 CPU M 480 @ 2.67GHz 上编译。
编辑:正如@Als 建议的那样,我将提供具有基本优化的版本(-O
GCC 中的标志)。