Chinaunix首页 | 论坛 | 博客
  • 博客访问: 998461
  • 博文数量: 21
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 216
  • 用 户 组: 普通用户
  • 注册时间: 2018-11-27 17:55
文章分类
文章存档

2019年(21)

我的朋友

分类: C/C++

2019-06-23 16:27:33

switch相比if else的实现,其优势是执行效率不会因为分支的增加而变慢。
这个是如何实现的嗯,一切的奥秘就在于有个跳转表。
注意,gcc编译switch时使用跳转表需要分支在4个以上(具体多少个看gcc的实现)

点击(此处)折叠或打开

  1. int switchtest(int a, int b, int c)
  2. {
  3.     int ret;
  4.     switch(a){
  5.         case 1:
  6.             ret = b+c;
  7.             break;
  8.         case 2:
  9.             ret = b+2*c;
  10.             break;
  11.         case 3:
  12.             ret = b+3*c;
  13.             break;
  14.         case 4:
  15.         case 5:
  16.             ret = b+5*c;
  17.     }
  18.     return ret;
  19. }
编译gcc -Og switch.c -S


汇编:

点击(此处)折叠或打开

  1. switchtest:
  2.     .frame    $sp,0,$31        # vars= 0, regs= 0/0, args= 0, gp= 0
  3.     .mask    0x00000000,0
  4.     .fmask    0x00000000,0
  5.     .set    noreorder
  6.     .set    nomacro
  7.     sltu    $24,$4,6   #把第一个入参跟6比较,如果小于6,就把$24置1;
  8.     beq    $24,$0,$L8  #如果$24为0,则跳到L8
  9.     sll    $4,$4,2   #把第一个入参逻辑左移两位,乘以4的意思,就是一个地址占用的字节数:)

  10.     lui    $24,%hi($L4) #把$L4的高字节存入$24的高字节
  11.     addiu    $24,$24,%lo($L4)  #把$L4的低字节和$24相加,这句加上面一句实际含义是$24 = $L4
  12.     addu    $4,$24,$4  #$4 = $24 + $4;(注意,此时$4中的地址都是4个字节4个字节加的,所以前面有个逻辑左移两位的操作
  13.     lw    $24,0($4)   #把$4中地址指向的值存入到寄存器 $24中
  14.     j    $24    #直接跳转到$24的地址
  15.     nop

  16.     .rdata
  17.     .align    2
  18.     .align    2
  19. $L4:                  #$L4是一个数组
  20.     .word    $L2      
  21.     .word    $L3      #case 1
  22.     .word    $L5      #case 2
  23.     .word    $L6      #case 3
  24.     .word    $L7      #case 4
  25.     .word    $L7      #case 5
  26.     .text
  27. $L3:
  28.     j    $31
  29.     addu    $2,$5,$6  #返回值等于第二个入参加第三个入参

  30. $L5:
  31.     sll    $6,$6,1
  32.     j    $31
  33.     addu    $2,$6,$#返回值等于第二个入参加(第三个入参*2

  34. $L6:
  35.     sll    $2,$6,1
  36.     addu    $6,$2,$6
  37.     j    $31
  38.     addu    $2,$6,$#返回值等于第二个入参加(第三个入参*3

  39. $L7:
  40.     sll    $2,$6,2
  41.     addu    $6,$2,$6
  42.     addu    $2,$6,$#返回值等于第二个入参加(第三个入参*5
  43. $L2:
  44. $L8:
  45.     j    $31
  46.     nop

阅读(278225) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~