c語言switch語句的組合語言實現
乙個好的編譯器一定是一群頂尖軟體高手們集體長時間創作的作品了
,所以研究研究編譯器的編譯過程就是在向這些高手們學習。說到底,編譯器也是乙個很好的老師了,它可以為我們揭開高階語言實現的奧秘,為那些永不滿足於表面現象的程式設計師深入掌握一門語言提供乙個很好的途徑。
來看看微軟的
cl 8.0
編譯器是怎樣來編譯
c語言的
switch
語句的,
照例寫乙個測試的例子:
inttest()
return 0;
} 看看生成的彙編**: ;
5:
; 6:switch(i)
movecx
, dword ptr _i$
[ebp]
movdword ptr tv64
[ebp
], ecx
;case 1:
cmpdword ptr tv64
[ebp
], 1
jeshort $ln3@test
;case 2:
cmpdword ptr tv64
[ebp
], 2
jeshort $ln2@test
;default:
jmpshort $ln1@test
$ln3@test:
; 7: ;
12:
; 13
: return 0;
xoreax
, eax
; 14: }
這段彙編**是很好理解的,就是比較並跳轉的過程。
下面看看乙個比較複雜的
switch
inttest()
return 0;
} 再來看看編譯器生成的彙編**:
; 5: ;
6: switch(i)
movecx
, dword ptr _i$
[ebp]
movdword ptr tv64
[ebp
], ecx
movedx
, dword ptr tv64
[ebp]
subedx, 1
movdword ptr tv64
[ebp
], edx
cmpdword ptr tv64
[ebp
], 3
jashort $ln1@test
moveax
, dword ptr tv64
[ebp]
jmpdword ptr $ln10@test
[eax*4
] ;
以上的彙編**相當於以下的偽指令:
if(i-1 > 3)
else
$ln10@test
是乙個跳轉表,通過它就可以跳轉到相應的處理**中去,看來微軟的編譯器還是很聰明的,會在編譯時對
case
的值作一些判斷,這也就是所謂的優化吧。
$ln5@test:
; 7:
......
$ln10@test:
dd$ln5@test
;case 1
dd$ln4@test
;case 2
dd$ln3@test
;case 3
dd$ln2@test
;case 4
下面來看看加大各
case
的差別會帶來怎樣的差異:
inttest()
return 0;
} 來看看編譯器產生的彙編**:
_testproc
; 2:
else
可見,對於
case
的值有較大的差別的情況編譯器還會新增乙個跳轉索引表,先通過
case
值找到對應的跳轉表的索引,然後通過索引再找到跳轉表中的跳轉位址。
$ln5@test:
; 7:
; 14
: ;
15:
return 0;
xoreax
, eax
; 16: }
movesp
, ebp
popebp
ret0
$ln11@test:
dd$ln5@test
dd$ln4@test
dd$ln3@test
dd$ln2@test
dd$ln1@test
$ln10@test:
db0
db1
db4
db4
db4
db4
db4
db4
db2
db4
db4
db4
db4
db4
db3
_testendp
我們再來進一步的加大
case
值的差別:
inttest()
return 0;
} 來看看生成的彙編**片斷: ;
5:
; 6:switch(i)
movecx
, dword ptr _i$
[ebp]
movdword ptr tv64
[ebp
], ecx
;大於250則跳轉到
$ln10@test,
即case 550
的情況
cmpdword ptr tv64
[ebp
], 250
; 000000f
ah
jgshort $ln10@test
case 250
cmpdword ptr tv64
[ebp
], 250
; 000000f
ah
jeshort $ln3@test
;case 1
cmpdword ptr tv64
[ebp
], 1
jeshort $ln5@test
;case 100
cmpdword ptr tv64
[ebp
], 100
; 00000064h
jeshort $ln4@test
;其它情況跳轉到
default
處的**
jmpshort $ln1@test
$ln10@test:
;case 550
cmpdword ptr tv64
[ebp
], 550
; 00000226h
jeshort $ln2@test
;其它情況跳轉到
default
處的**
jmpshort $ln1@test
$ln5@test:
哈哈,這與第一種情況很相似吧!好端端的**被編譯器處理得有點複雜,但是又滴水不漏。當然,編譯器也是先判斷了具體的值以後才對進行處理的。這時候,編譯器一定在衡量了時間與空間的損失後作出這樣的決定的,如果用第三種查表的方法繼續編譯空間損失會很大
,需要乙個很長的**
,在這種情況下,編譯器選擇了損失時間而節省空間。
C語言初階 分支語句,if語句,switch語句
2switch語句 注意事項 if 表示式 2 二選一 if 表示式 else 3 多分支 多選一 if 表示式1 else if 表示式2 else 1.if語句是選擇分支語句,只要滿足乙個條件則其他語句就不執行了。2.if後 括號 判斷的是括號中表示式返回的結果。在c語言中,0為假,非0為真。3...
C語言switch語句
switch語句 switch 表示式 case 常量表示式 1 語句1 case 常量表示式 2 語句2 case 常量表示式 n 語句n default 語句 n 1 說明 1 switch後面括號內的表示式,其值可以使整形 字元型 列舉型資料 2 應該在執行乙個case 分支後,使流程跳出 s...
C語言switch語句
既然有了if else 組合為什麼還需要switch case 組合呢?那你既然有了菜刀為什麼還需要水果刀呢?你總不能扛著雲長的青龍偃月刀 又名冷豔鋸 去削蘋果吧。如果你真能做到,關二爺也會佩服你的。if else 一般表示兩個分支或是巢狀表示少量的分支,但如果分支很多的話 還是用switch ca...