簡體   English   中英

gcc objdump程序集調試

[英]gcc objdump assembly debugging

我正在嘗試將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目的地?

運行objdump命令時,您沒有反匯編最終的可執行文件,而是反匯編了由編譯器生成的目標文件( test.o )。 我對您執行了類似的步驟(使用您的代碼)(在GDB中編譯並運行objdumpdissas ),除了我對鏈接的可執行文件而不是對目標文件執行了objdump (這意味着我沒有使用-c標志進行編譯)。 輸出如下:

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.

如您所見,這兩個反匯編是相同的,除了一些小的語法差異(例如,GDB的前綴是0x )。

默認情況下, objdump缺少的是重定位。

使用-r標志運行objdump可以看到這些。 例如

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM