今天上课讲了switch语句,我个人不是很懂,附上c语言代码
可以看到这里si\witch语句的变量n的变化范围是-2到15
书上也说了,当switch语句变量n很大的时候,就会采用跳转表
gcc -S 1121.c -o temp.s
得到汇编代码表示:
main:
.LFB0:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl %esp, %ebp
.cfi_def_cfa_register 5
andl $-16, %esp
subl $32, %esp
movl $-1, 28(%esp) n为负数
movl 28(%esp), %eax
addl $2, %eax 把n变成正数-1+2=1,也就是说使用无符号数来进行比较的。
cmpl $17, %eax
ja .L2
movl .L4(,%eax,4), %eax 跳转到相应的case语句中所对应的块区域的首地址中。
jmp *%eax
.section .rodata
.align 4
.align 4
.L4: 跳转表
.long .L3
.long .L2
.long .L2
.long .L2
.long .L5
.long .L2
.long .L6
.long .L7
.long .L8
.long .L9
.long .L10
.long .L2
.long .L2
.long .L11
.long .L12
.long .L2
.long .L2
.long .L13
.text
.L3:
addl $1, 28(%esp)
jmp .L14
.L5:
subl $1, 28(%esp)
jmp .L14
.L6:
addl $2, 28(%esp)
jmp .L14
.L7:
addl $2, 28(%esp)
jmp .L14
.L8:
addl $2, 28(%esp)
jmp .L14
.L9:
addl $2, 28(%esp)
jmp .L14
.L10:
addl $2, 28(%esp)
jmp .L14
.L11:
addl $2, 28(%esp)
jmp .L14
.L12:
addl $2, 28(%esp)
jmp .L14
.L13:
addl $2, 28(%esp)
jmp .L14
.L2:
movl $0, 28(%esp)
nop
.L14:
movl 28(%esp), %eax
movl %eax, 4(%esp)
movl $.LC0, (%esp)
call printf
movl $0, %eax
leave
.cfi_restore 5
.cfi_def_cfa 4, 4
ret
.cfi_endproc
上述代码中的.L4就是跳转表。
00000000 <main>:
0: 55 push %ebp
1: 89 e5 mov %esp,%ebp
3: 83 e4 f0 and $0xfffffff0,%esp
6: 83 ec 20 sub $0x20,%esp
9: c7 44 24 1c ff ff ff movl $0xffffffff,0x1c(%esp)
10: ff
11: 8b 44 24 1c mov 0x1c(%esp),%eax
15: 83 c0 02 add $0x2,%eax
18: 83 f8 11 cmp $0x11,%eax switch语句的变化范围从
1b: 77 4f ja 6c <main+0x6c>
1d: 8b 04 85 04 00 00 00 mov 0x4(,%eax,4),%eax
24: ff e0 jmp *%eax
26: 83 44 24 1c 01 addl $0x1,0x1c(%esp)
2b: eb 48 jmp 75 <main+0x75>
2d: 83 6c 24 1c 01 subl $0x1,0x1c(%esp)
32: eb 41 jmp 75 <main+0x75>
34: 83 44 24 1c 02 addl $0x2,0x1c(%esp)
39: eb 3a jmp 75 <main+0x75>
3b: 83 44 24 1c 02 addl $0x2,0x1c(%esp)
40: eb 33 jmp 75 <main+0x75>
42: 83 44 24 1c 02 addl $0x2,0x1c(%esp)
47: eb 2c jmp 75 <main+0x75>
49: 83 44 24 1c 02 addl $0x2,0x1c(%esp)
4e: eb 25 jmp 75 <main+0x75>
50: 83 44 24 1c 02 addl $0x2,0x1c(%esp)
55: eb 1e jmp 75 <main+0x75>
57: 83 44 24 1c 02 addl $0x2,0x1c(%esp)
5c: eb 17 jmp 75 <main+0x75>
5e: 83 44 24 1c 02 addl $0x2,0x1c(%esp)
63: eb 10 jmp 75 <main+0x75>
65: 83 44 24 1c 02 addl $0x2,0x1c(%esp)
6a: eb 09 jmp 75 <main+0x75>
6c: c7 44 24 1c 00 00 00 movl $0x0,0x1c(%esp)
73: 00
74: 90 nop
75: 8b 44 24 1c mov 0x1c(%esp),%eax
79: 89 44 24 04 mov %eax,0x4(%esp)
7d: c7 04 24 00 00 00 00 movl $0x0,(%esp)
84: e8 fc ff ff ff call 85 <main+0x85>
89: b8 00 00 00 00 mov $0x0,%eax
8e: c9 leave
8f: c3 ret .