switch相比if else的实现,其优势是执行效率不会因为分支的增加而变慢。
这个是如何实现的嗯,一切的奥秘就在于有个跳转表。
注意,gcc编译switch时使用跳转表需要分支在4个以上(具体多少个看gcc的实现)
-
int switchtest(int a, int b, int c)
-
{
-
int ret;
-
switch(a){
-
case 1:
-
ret = b+c;
-
break;
-
case 2:
-
ret = b+2*c;
-
break;
-
case 3:
-
ret = b+3*c;
-
break;
-
case 4:
-
case 5:
-
ret = b+5*c;
-
}
-
return ret;
-
}
编译gcc -Og switch.c -S
汇编:
-
switchtest:
-
.frame $sp,0,$31 # vars= 0, regs= 0/0, args= 0, gp= 0
-
.mask 0x00000000,0
-
.fmask 0x00000000,0
-
.set noreorder
-
.set nomacro
-
sltu $24,$4,6 #把第一个入参跟6比较,如果小于6,就把$24置1;
-
beq $24,$0,$L8 #如果$24为0,则跳到L8
-
sll $4,$4,2 #把第一个入参逻辑左移两位,乘以4的意思,就是一个地址占用的字节数:)
-
-
lui $24,%hi($L4) #把$L4的高字节存入$24的高字节
-
addiu $24,$24,%lo($L4) #把$L4的低字节和$24相加,这句加上面一句实际含义是$24 = $L4
-
addu $4,$24,$4 #$4 = $24 + $4;(注意,此时$4中的地址都是4个字节4个字节加的,所以前面有个逻辑左移两位的操作)
-
lw $24,0($4) #把$4中地址指向的值存入到寄存器 $24中
-
j $24 #直接跳转到$24的地址
-
nop
-
-
.rdata
-
.align 2
-
.align 2
-
$L4: #$L4是一个数组
-
.word $L2
-
.word $L3 #case 1
-
.word $L5 #case 2
-
.word $L6 #case 3
-
.word $L7 #case 4
-
.word $L7 #case 5
-
.text
-
$L3:
-
j $31
-
addu $2,$5,$6 #返回值等于第二个入参加第三个入参
-
-
$L5:
-
sll $6,$6,1
-
j $31
-
addu $2,$6,$5 #返回值等于第二个入参加(第三个入参*2)
-
-
$L6:
-
sll $2,$6,1
-
addu $6,$2,$6
-
j $31
-
addu $2,$6,$5 #返回值等于第二个入参加(第三个入参*3)
-
-
$L7:
-
sll $2,$6,2
-
addu $6,$2,$6
-
addu $2,$6,$5 #返回值等于第二个入参加(第三个入参*5)
-
$L2:
-
$L8:
-
j $31
-
nop
阅读(278225) | 评论(0) | 转发(0) |