如何解释 objdump 反汇编输出列?

Spe*_*ngs -1 x86 assembly endianness disassembly att

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

在此处输入图片说明

我有多个问题,所以这里是:

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

Pet*_*des 5

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

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

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


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

[prefixes] opcode [modrm [SIB] displacement0/8/32] [immediate8/32]
Run Code Online (Sandbox Code Playgroud)

操作码可以是单个字节,或在存储器中顺序指定的字节的序列英特尔/ AMD的文档,例如,在0F AF /r用于imul reg, reg/mem

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

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

例如,mov $0x12345678, %eaxfoo.s,组装gcc -c foo.s到一个.o,反汇编为:

  0:   b8 78 56 34 12          mov    $0x12345678,%eax
Run Code Online (Sandbox Code Playgroud)

另请参阅SO 的 x86 标签 wiki 中x86 文档/手册的更多链接,包括英特尔的 PDF 手册