1

I'm learning Assembly. I wrote the below c program containing switch case, created the object file(gcc -o filename filename.c), then took the object dump. But I didn't find the Labels and jump tables in the object dump.

Can anybody tell me why the jump table is not getting generated ? Like the ones mention here Link

Code

C file

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;
}

Below is the main section

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

Below is the .rodata section

Disassembly of section .rodata:

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

Can anybody let me know why this is behaving like this? Thanks in Advance

9
  • 4
    Did you look at what's at 804861c? Commented Sep 22, 2014 at 9:12
  • Apart from what @harold asks, there is no guarantee a compiler will generate a jump table for your code. Commented Sep 22, 2014 at 9:25
  • If your compiler has it, don't use a disassembler but use an option like -S directly to produce the assembler. Usually this is far more readable since it still has labels and not just jump addresses. Commented Sep 22, 2014 at 10:08
  • @harold Sorry if I misunderstood u ...are you asking me to use gdb to check the address 804861c ? Commented Sep 22, 2014 at 17:42
  • @user3538267 yes, and check it as dwords, trying to disassemble it will be useless. Commented Sep 22, 2014 at 17:45

1 Answer 1

1

Your jump table is located at address 0x804861c. If you dump this address, I'm pretty sure, you'll find the values 0x804845f, 0x804847d, 0x804849b, etc. since these values correspond to the addresses of the branches of the switch statement. What happens is that first it is ensured that the value of i (0x1c(%esp))is between 0 and 6 (and jump if above, ja, to last printf) and if it is between, uses its value multiplied by 4 (sizeof addresses on your architecture) as an offset into the jump table (0x804861c(,%eax,4),%eax).

I'm not sure what you're looking for exactly, or what you're trying to achieve, but as @Jens Gustedt pointed out, you should use the -S switch if you want to observe the assembly generated.

Additionally, beware that your code can easily be optimised by the compiler, i.e. as soon as you use the -O switch your assembly will probably shrink down to the last printf and the return statement, since the whole code execution can be predicted and useless parts can be omitted.

Sign up to request clarification or add additional context in comments.

4 Comments

Actually the code ensures that i is between 0 and 6 (@ 804844a) by adding 1 to the original range -1..5.
@Jongware Yes, you're right. Updated the post to reflect this, thanks!
@grasbueschel can you tell me what do you mean by dumping the address 0x804861c, what exactly do I need to do? I just want to see how a simple c program with switch statements gets converted to jump table
@user3538267 compile with the -S switch. The generated assembly will be much clearer than the compiled version, i.e. no addresses to dump, just code to read...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.