首页 > 解决方案 > gcc objdump 汇编调试

问题描述

我正在尝试将 C 代码更改为汇编代码。

起初,我使用 gcc 和 objdump 函数从 c 代码中提取汇编代码。

C 代码只是简单的 printf 代码。

#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 

在这个汇编代码中,我很好奇为什么 callq 指令的目标是 e

所以我在 gdb 中使用

主要的

    (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 

在这段代码中,我假设 0x400400 是 printf 函数的地址。

为什么 objdump 和 gdb 的汇编代码显示不同的结果?

如何让 objdump 结果显示正确的 callq 目的地?

标签: cgccassemblygdbdisassembly

解决方案


默认情况下,您缺少objdump的是重定位。

objdump带着旗帜跑-r可以让你看到这些。例如

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   

向我们展示调用将使用 PC 相对地址,指向puts


推荐阅读