在汇编代码中找不到跳转表

时间:2014-09-22 09:09:45

标签: c assembly switch-statement jump-table

我正在学习大会。我写下了包含switch case的下面的c程序,创建了目标文件(gcc -o filename filename.c),然后进行了对象转储。但是我没有在对象转储中找到标签和跳转表。

有人能告诉我为什么没有生成跳转表吗?就像这里提到的那些 Link

代码

C档

int main() {
  int i = 0;
  int n = 9, z = 99 , p = 999;
  switch( i ) 
    {
      case -1:
      n++;
      printf("value n=%d",n);
      break;
      case 0 :
      z++;
      printf("value z=%d",z);
      break;
      case 1 :
      p++;
      printf("value p=%d",p);
      break;
      case 2 :
      p++;
      printf("value p=%d",p);
      break;
      case 3 :
      p++;
      printf("value p=%d",p);
      break;
      case 4 :
      p++;
      printf("value p=%d",p);
      break;
      case 5 :
      p++;
      printf("value p=%d",p);
      break;

   }
  printf("Values n=%d z=%d p=%d \n",n,z,p);
  return 0;
}

以下是主要部分

0804841d <main>:
 804841d:   55                      push   %ebp
 804841e:   89 e5                   mov    %esp,%ebp
 8048420:   83 e4 f0                and    $0xfffffff0,%esp
 8048423:   83 ec 20                sub    $0x20,%esp
 8048426:   c7 44 24 1c 00 00 00    movl   $0x0,0x1c(%esp)
 804842d:   00 
 804842e:   c7 44 24 10 09 00 00    movl   $0x9,0x10(%esp)
 8048435:   00 
 8048436:   c7 44 24 14 63 00 00    movl   $0x63,0x14(%esp)
 804843d:   00 
 804843e:   c7 44 24 18 e7 03 00    movl   $0x3e7,0x18(%esp)
 8048445:   00 
 8048446:   8b 44 24 1c             mov    0x1c(%esp),%eax
 804844a:   83 c0 01                add    $0x1,%eax
 804844d:   83 f8 06                cmp    $0x6,%eax
 8048450:   0f 87 cb 00 00 00       ja     8048521 <main+0x104>
 8048456:   8b 04 85 1c 86 04 08    mov    0x804861c(,%eax,4),%eax
 804845d:   ff e0                   jmp    *%eax
 804845f:   83 44 24 10 01          addl   $0x1,0x10(%esp)
 8048464:   8b 44 24 10             mov    0x10(%esp),%eax
 8048468:   89 44 24 04             mov    %eax,0x4(%esp)
 804846c:   c7 04 24 e0 85 04 08    movl   $0x80485e0,(%esp)
 8048473:   e8 78 fe ff ff          call   80482f0 <printf@plt>
 8048478:   e9 a4 00 00 00          jmp    8048521 <main+0x104>
 804847d:   83 44 24 14 01          addl   $0x1,0x14(%esp)
 8048482:   8b 44 24 14             mov    0x14(%esp),%eax
 8048486:   89 44 24 04             mov    %eax,0x4(%esp)
 804848a:   c7 04 24 eb 85 04 08    movl   $0x80485eb,(%esp)
 8048491:   e8 5a fe ff ff          call   80482f0 <printf@plt>
 8048496:   e9 86 00 00 00          jmp    8048521 <main+0x104>
 804849b:   83 44 24 18 01          addl   $0x1,0x18(%esp)
 80484a0:   8b 44 24 18             mov    0x18(%esp),%eax
 80484a4:   89 44 24 04             mov    %eax,0x4(%esp)
 80484a8:   c7 04 24 f6 85 04 08    movl   $0x80485f6,(%esp)
 80484af:   e8 3c fe ff ff          call   80482f0 <printf@plt>
 80484b4:   eb 6b                   jmp    8048521 <main+0x104>
 80484b6:   83 44 24 18 01          addl   $0x1,0x18(%esp)
 80484bb:   8b 44 24 18             mov    0x18(%esp),%eax
 80484bf:   89 44 24 04             mov    %eax,0x4(%esp)
 80484c3:   c7 04 24 f6 85 04 08    movl   $0x80485f6,(%esp)
 80484ca:   e8 21 fe ff ff          call   80482f0 <printf@plt>
 80484cf:   eb 50                   jmp    8048521 <main+0x104>
 80484d1:   83 44 24 18 01          addl   $0x1,0x18(%esp)
 80484d6:   8b 44 24 18             mov    0x18(%esp),%eax
 80484da:   89 44 24 04             mov    %eax,0x4(%esp)
 80484de:   c7 04 24 f6 85 04 08    movl   $0x80485f6,(%esp)
 80484e5:   e8 06 fe ff ff          call   80482f0 <printf@plt>
 80484ea:   eb 35                   jmp    8048521 <main+0x104>
 80484ec:   83 44 24 18 01          addl   $0x1,0x18(%esp)
 80484f1:   8b 44 24 18             mov    0x18(%esp),%eax
 80484f5:   89 44 24 04             mov    %eax,0x4(%esp)
 80484f9:   c7 04 24 f6 85 04 08    movl   $0x80485f6,(%esp)
 8048500:   e8 eb fd ff ff          call   80482f0 <printf@plt>
 8048505:   eb 1a                   jmp    8048521 <main+0x104>
 8048507:   83 44 24 18 01          addl   $0x1,0x18(%esp)
 804850c:   8b 44 24 18             mov    0x18(%esp),%eax
 8048510:   89 44 24 04             mov    %eax,0x4(%esp)
 8048514:   c7 04 24 f6 85 04 08    movl   $0x80485f6,(%esp)
 804851b:   e8 d0 fd ff ff          call   80482f0 <printf@plt>
 8048520:   90                      nop
 8048521:   8b 44 24 18             mov    0x18(%esp),%eax
 8048525:   89 44 24 0c             mov    %eax,0xc(%esp)
 8048529:   8b 44 24 14             mov    0x14(%esp),%eax
 804852d:   89 44 24 08             mov    %eax,0x8(%esp)
 8048531:   8b 44 24 10             mov    0x10(%esp),%eax
 8048535:   89 44 24 04             mov    %eax,0x4(%esp)
 8048539:   c7 04 24 01 86 04 08    movl   $0x8048601,(%esp)
 8048540:   e8 ab fd ff ff          call   80482f0 <printf@plt>
 8048545:   b8 00 00 00 00          mov    $0x0,%eax
 804854a:   c9                      leave  
 804854b:   c3                      ret    
 804854c:   66 90                   xchg   %ax,%ax
 804854e:   66 90                   xchg   %ax,%ax

以下是.rodata部分

Disassembly of section .rodata:

080485d8 <_fp_hw>:
 80485d8:   03 00                   add    (%eax),%eax
    ...

任何人都可以告诉我为什么会这样吗? 在此先感谢

1 个答案:

答案 0 :(得分:1)

您的跳转表位于地址0x804861c。如果您转储此地址,我很确定,您会找到值0x804845f0x804847d0x804849b等,因为这些值对应于分支的地址切换声明。 会发生的是,首先确保i0x1c(%esp))的值在0到6之间(如果在上面跳跃,ja到最后一次printf),如果它在,使用其值乘以4(架构中的sizeof地址)作为跳转表(0x804861c(,%eax,4),%eax)的偏移量。

我不确定你要找的是什么,或者你想要达到的目的,但正如@Jens Gustedt指出的那样,如果你想观察装配,你应该使用-S开关生成。

此外,请注意编译器可以轻松优化您的代码,即只要您使用-O开关,程序集可能会缩小到最后一个printf和return语句,因为整个代码执行可以预测,无用的部分可以省略。