1

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

谁能告诉我为什么没有生成跳转表?就像这里提到的 链接

代码

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
    ...

谁能让我知道为什么会这样?提前致谢

4

1 回答 1

1

您的跳转表位于 address 0x804861c。如果您转储此地址,我敢肯定,您会找到值0x804845f0x804847d0x804849b等,因为这些值对应于 switch 语句分支的地址。发生的情况是,首先确保i( 0x1c(%esp)) 的值在 0 到 6 之间(如果高于 ,则跳转ja到最后一个 printf ),如果介于两者之间,则使用其值乘以 4 (架构上的 sizeof 地址)作为跳转表 ( 0x804861c(,%eax,4),%eax) 中的偏移量。

我不确定你到底在寻找什么,或者你想要实现什么,但正如@Jens Gustedt 指出的那样,-S如果你想观察生成的程序集,你应该使用开关。

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

于 2014-09-22T10:56:22.140 回答