【问题标题】:How to interpret objdump disassembly output columns?如何解释 objdump 反汇编输出列?
【发布时间】:2020-07-09 07:43:16
【问题描述】:

我用 c 编写了一个简单的程序,它调用一个名为 while_loop 的函数,参数为 4,3,2。该函数基本上只是一个while循环,我认为它与我的问题并不相关,因为它更像是一个通用问题。有人告诉我运行 objdump -d,所以我这样做了。

我有多个问题,所以就这样吧:

  1. 我知道在最左边的列中有地址,它们根据前面的字节数递增。我不太明白的是第二列。是正在执行的指令但是是十六进制的吗?这是否意味着 push %ebp 等于 55 ?我不太明白。
  2. 因为这是 IA-32 并且它是小端,我知道最低有效字节存储在最低地址。但是,我不明白这些字节的显示顺序是否与它们在内存中的位置有关。看第 3 行,“8b 55 10”这是否意味着最低地址中有 8b,我会反过来读,或者这是否意味着 10 在最低地址,我会反过来读?
  3. 左边的这些地址是绝对内存地址还是相对地址?

【问题讨论】:

  • objdump -drwC 输出作为文本复制/粘贴到代码格式化块中,而不是图像中。
  • 1) 是的。如果您对机器代码编码感兴趣,请查阅指令集参考手册。 2) 是8b 是最低地址。您需要交换多字节值,但您的示例中没有。 3) 绝对但虚拟。
  • 我对您的问题投了反对票,因为您发布了一张代码图片。当您用文本替换它时,将收回反对票。

标签: assembly x86 endianness disassembly att


【解决方案1】:

在这种情况下,您的地址是绝对的,因为您有一个位置相关可执行文件(不是 PIE)。 ELF 元数据中有一个字段(由链接器设置),它指定映射可执行文件的虚拟地址。您可以使用readelf -a 来查看更多内容。

在 PIE 可执行文件中,十六进制地址将相对于“图像库”,这通常意味着相对于文件的开头。 (类似于.o,其中地址从.text 部分开头的0 开始计算)。您可以使用--adjust-vma=offset 设置打印这些地址的基地址。

是的,第 2 列是机器代码的十六进制转储,按内存顺序显示为单个字节。 Objdump 不会将它们解释为 little-endian-words 或类似的东西,只是每字节一对十六进制数字,按地址递增的顺序。


x86 机器码基本上是一个字节流。指令由

组成
[prefixes] opcode [modrm [SIB] displacement0/8/32] [immediate8/32]

操作码可以是单个字节,也可以是 Intel / AMD 文档中按内存顺序指定的字节序列,例如0F AF /rimul reg, reg/mem

有些指令有 16 位立即数,但如果有的话,通常是 1 或 4 个字节。

字节序仅与寻址模式中的多字节位移或多字节立即数有关。

例如mov $0x12345678, %eaxfoo.s 中,与 gcc -c foo.s 组装成 .o,反汇编为:

  0:   b8 78 56 34 12          mov    $0x12345678,%eax

另请参阅SO's x86 tag wiki 中指向 x86 文档/手册的更多链接,包括英特尔的 PDF 手册

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-04
    • 1970-01-01
    • 2012-05-14
    • 2014-05-11
    • 2013-06-11
    相关资源
    最近更新 更多