0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

C言語 switch及びifelseの違いをアセンブリ上で確認

Last updated at Posted at 2025-05-01

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

image.png

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
0
0
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?