【问题标题】:Jump Table not found in Assembly code在汇编代码中找不到跳转表
【发布时间】:2014-11-16 04:45:42
【问题描述】:

我正在学习汇编。我编写了以下包含 switch case 的 c 程序,创建了目标文件(gcc -o 文件名 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
    ...

谁能告诉我为什么会这样? 提前致谢

【问题讨论】:

  • 你看过 804861c 的内容了吗?
  • 除了@harold 的要求之外,不能保证编译器会为您的代码生成跳转表。
  • 如果你的编译器有它,不要使用反汇编器,而是直接使用-S 之类的选项来生成汇编器。通常这更具可读性,因为它仍然有标签,而不仅仅是跳转地址。
  • @harold 对不起,如果我误解了你……你是要我使用 gdb 来检查地址 804861c 吗?
  • @user3538267 是的,把它检查为 dwords,试图反汇编它是没有用的。

标签: c assembly switch-statement jump-table


【解决方案1】:

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

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

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

【讨论】:

  • 实际上代码确保i 介于0 和6 (@804844a) 之间,方法是在original 范围-1..5 中加1 .
  • @Jongware 是的,你是对的。更新帖子以反映这一点,谢谢!
  • @grasbueschel 你能告诉我转储地址 0x804861c 是什么意思吗,我到底需要做什么?我只是想看看一个简单的带有 switch 语句的 c 程序是如何转换为跳转表的
  • @user3538267 使用-S 开关进行编译。生成的程序集将比编译版本更清晰,即没有要转储的地址,只需读取代码......
猜你喜欢
  • 2015-04-08
  • 1970-01-01
  • 2015-12-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-18
  • 2018-02-06
相关资源
最近更新 更多