6

I'm trying to change C code to assembly code.

At first, i used gcc and objdump function to extract assembly code from c code.

The C code was just simple printf code.

#include <stdio.h>

int main(){
    printf("this\n");
    return 0;
}


gcc -c -S -O0 test.c
objdump -dS test.o > test.txt

0000000000000000 <main>:
   0:   55                      push   %rbp
   1:   48 89 e5                mov    %rsp,%rbp
   4:   bf 00 00 00 00          mov    $0x0,%edi
   9:   e8 00 00 00 00          callq  e <main+0xe>
   e:   b8 00 00 00 00          mov    $0x0,%eax
  13:   5d                      pop    %rbp 
  14:   c3                      retq 

in this assembly code, i was curious why callq instructions destination is e

so i run this code in gdb using

disas main

    (gdb) disas main
Dump of assembler code for function main:
   0x0000000000400526 <+0>: push   %rbp
   0x0000000000400527 <+1>: mov    %rsp,%rbp
   0x000000000040052a <+4>: mov    $0x4005c4,%edi
   0x000000000040052f <+9>: callq  0x400400 <puts@plt>
   0x0000000000400534 <+14>: mov    $0x0,%eax
   0x0000000000400539 <+19>: pop    %rbp
   0x000000000040053a <+20>: retq 

in this code, i assumed that 0x400400 is the address of printf function.

Why does objdump and gdb's assembly code show different result?

How can i make objdump result shows the right callq destination?

1
  • 2
    Because the code has not been linked, the destination address for the call is just 00 00 00 00. The linker will patch this when you link your executable. Commented Aug 29, 2018 at 7:45

2 Answers 2

4

When you run the objdump command you are not disassembling the final executable, you are disassembling the object file produced by the compiler (test.o). I performed similar steps (using your code) to you (compiling and running objdump and dissas in GDB) except I performed the objdump on the linked executable not on the object file (this means I did not compile with the -c flag). The outputs are below:

objdump -dS a.out:
1140:       55                      push   %rbp
1141:       48 89 e5                mov    %rsp,%rbp
1144:       48 83 ec 10             sub    $0x10,%rsp
1148:       48 8d 3d b5 0e 00 00    lea    0xeb5(%rip),%rdi        # 2004 <_IO_stdin_used+0x4>
114f:       c7 45 fc 00 00 00 00    movl   $0x0,-0x4(%rbp)
1156:       b0 00                   mov    $0x0,%al
1158:       e8 d3 fe ff ff          callq  1030 <printf@plt>
115d:       31 c9                   xor    %ecx,%ecx
115f:       89 45 f8                mov    %eax,-0x8(%rbp)
1162:       89 c8                   mov    %ecx,%eax
1164:       48 83 c4 10             add    $0x10,%rsp
1168:       5d                      pop    %rbp
1169:       c3                      retq   
116a:       66 0f 1f 44 00 00       nopw   0x0(%rax,%rax,1)

GDB:

(gdb) disas main
Dump of assembler code for function main:
   0x0000000000001140 <+0>:     push   %rbp
   0x0000000000001141 <+1>:     mov    %rsp,%rbp
   0x0000000000001144 <+4>:     sub    $0x10,%rsp
   0x0000000000001148 <+8>:     lea    0xeb5(%rip),%rdi        # 0x2004
   0x000000000000114f <+15>:    movl   $0x0,-0x4(%rbp)
   0x0000000000001156 <+22>:    mov    $0x0,%al
   0x0000000000001158 <+24>:    callq  0x1030 <printf@plt>
   0x000000000000115d <+29>:    xor    %ecx,%ecx
   0x000000000000115f <+31>:    mov    %eax,-0x8(%rbp)
   0x0000000000001162 <+34>:    mov    %ecx,%eax
   0x0000000000001164 <+36>:    add    $0x10,%rsp
   0x0000000000001168 <+40>:    pop    %rbp
   0x0000000000001169 <+41>:    retq   
End of assembler dump.

As you can see, the two disassemblies are the same, except for some minor syntax differences (e.g. GDB prefixes it's addresses with 0x).

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

Comments

3

What you're missing with objdump by default is relocations.

Running objdump with the -r flag lets you see these. e.g.

objdump -Sr foo.o

foo.o:     file format elf64-x86-64


Disassembly of section .text:

0000000000000000 <main>:
   0:   55                      push   %rbp
   1:   48 89 e5                mov    %rsp,%rbp
   4:   bf 00 00 00 00          mov    $0x0,%edi
            5: R_X86_64_32  .rodata
   9:   e8 00 00 00 00          callq  e <main+0xe>
            a: R_X86_64_PC32    puts-0x4
   e:   b8 00 00 00 00          mov    $0x0,%eax
  13:   5d                      pop    %rbp
  14:   c3                      retq   

Shows us that the call will use a PC relative address, pointing to puts

Comments

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.