switch
Cソース
switch.c
int main(){
int a=0;
int b=0;
switch(a){
case 1:
b=4;
break;
case 2:
b=5;
break;
case 3:
b=6;
break;
default:
b=7;
}
return 0;
}
アセンブリ
switch.s
switch.s
.file "switch.c"
.intel_syntax noprefix
.def ___main; .scl 2; .type 32; .endef
.text
.globl _main
.def _main; .scl 2; .type 32; .endef
_main:
LFB0:
.cfi_startproc
push ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
mov ebp, esp
.cfi_def_cfa_register 5
and esp, -16
sub esp, 16
call ___main
mov DWORD PTR [esp+12], 0
mov DWORD PTR [esp+8], 0
mov eax, DWORD PTR [esp+12]
cmp eax, 2
je L3
cmp eax, 3
je L4
cmp eax, 1
jne L8
mov DWORD PTR [esp+8], 4
jmp L6
L3:
mov DWORD PTR [esp+8], 5
jmp L6
L4:
mov DWORD PTR [esp+8], 6
jmp L6
L8:
mov DWORD PTR [esp+8], 7
L6:
mov eax, 0
leave
.cfi_restore 5
.cfi_def_cfa 4, 4
ret
.cfi_endproc
LFE0:
.ident "GCC: (MinGW.org GCC-6.3.0-1) 6.3.0"
if else
Cソース
ifelse.c
int main(){
int a=0;
int b=0;
if(a==1){
b=4;
}else if(a==2){
b=5;
}else if(a==3){
b=6;
}else{
b=7;
}
return 0;
}
アセンブリ
ifelse.s
ifelse.s
.file "ifelse.c"
.intel_syntax noprefix
.def ___main; .scl 2; .type 32; .endef
.text
.globl _main
.def _main; .scl 2; .type 32; .endef
_main:
LFB0:
.cfi_startproc
push ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
mov ebp, esp
.cfi_def_cfa_register 5
and esp, -16
sub esp, 16
call ___main
mov DWORD PTR [esp+12], 0
mov DWORD PTR [esp+8], 0
cmp DWORD PTR [esp+12], 1
jne L2
mov DWORD PTR [esp+8], 4
jmp L3
L2:
cmp DWORD PTR [esp+12], 2
jne L4
mov DWORD PTR [esp+8], 5
jmp L3
L4:
cmp DWORD PTR [esp+12], 3
jne L5
mov DWORD PTR [esp+8], 6
jmp L3
L5:
mov DWORD PTR [esp+8], 7
L3:
mov eax, 0
leave
.cfi_restore 5
.cfi_def_cfa 4, 4
ret
.cfi_endproc
LFE0:
.ident "GCC: (MinGW.org GCC-6.3.0-1) 6.3.0"
比較
winmergi
switchの関連部分
call ___main
mov DWORD PTR [esp+12], 0
mov DWORD PTR [esp+8], 0
mov eax, DWORD PTR [esp+12]
cmp eax, 2
je L3
cmp eax, 3
je L4
cmp eax, 1
jne L8
mov DWORD PTR [esp+8], 4
jmp L6
L3:
mov DWORD PTR [esp+8], 5
jmp L6
L4:
mov DWORD PTR [esp+8], 6
jmp L6
L8:
mov DWORD PTR [esp+8], 7
ifelseの関連部分
call ___main
mov DWORD PTR [esp+12], 0
mov DWORD PTR [esp+8], 0
cmp DWORD PTR [esp+12], 1
jne L2
mov DWORD PTR [esp+8], 4
jmp L3
L2:
cmp DWORD PTR [esp+12], 2
jne L4
mov DWORD PTR [esp+8], 5
jmp L3
L4:
cmp DWORD PTR [esp+12], 3
jne L5
mov DWORD PTR [esp+8], 6
jmp L3
L5:
mov DWORD PTR [esp+8], 7
cmpで比較→該当処理のラベルへ跳ぶ→代入処理
とやっていることは変わらないがswitch文を使用した場合の方がすっきりとしたコードが出力された。
理由は分からない。
動作環境
windows7 Version6.1.7601
GCC-6.3.0-1
(帰省中につき一時的に昔のパソコンを使用している。windows7が懐かしい。。。)
gcc -S -masm=intel switch.c -o switch.s