ndisasm手册中提到的二进制文件和可执行文件有什么区别?

What's the difference between binary and executable files mentioned in ndisasm's manual?

我想用 clang 编译我的 C 文件,然后用 ndisasm 反编译它(用于教育目的)。但是,ndisasm 在它的手册中说它只适用于 binary 而不是 executable files:

   ndisasm only disassembles binary files: it  has
   no  understanding  of  the  header  information
   present in object or executable files.  If  you
   want  to disassemble an object file, you should
   probably be using objdump(1).

究竟有什么区别?当我使用一个简单的 C 文件、可执行文件或二进制文件 运行 时,clang 会输出什么?

目标文件包含机器语言代码,各种其他信息。听起来 ndisasm 只想要机器代码,而不是其他东西。因此,该消息告诉您使用 objdump 实用程序从目标文件中仅提取机器代码段。那么你大概可以 运行 ndisasm 就可以了。

And what does clang output when I run it with a simple C file, an executable or a binary?

C 编译器通常能够创建一个 'raw' 二进制文件,即 Just The Code,拿着番茄,因为对于某些(罕见!)用途可能很有用。想想,例如,引导扇区(不能 'load' 以常规方式执行的可执行文件,因为加载它们的 OS 尚未启动)和可编程 RAM 芯片。操作系统本身通常不喜欢执行 'raw binary code' - 几乎出于相同的原因。一个例外是 MS Windows,它仍然可以 运行 旧格式 .com 二进制文件。

默认情况下,clang 会创建一个可执行文件。称为 object files 的中间文件通常在可执行文件被 linked 后删除(与库粘合在一起功能和适当的可执行文件 header)。要仅获取 .o object 文件,请使用 -c 开关。

请注意 Object 文件还包含一个 header。毕竟,linker 在 link 到其他部分之前需要知道文件包含什么。

出于教育目的,您可能需要检查 object 文件格式。有了这些知识,应该可以编写一个程序,该程序可以 告诉 您实际代码在文件中的哪个偏移量开始。然后您可以将该信息输入 ndisasm.

除了 header 之外,文件在指令后可能包含更多数据。同样,ndisasm 不知道也不关心。如果您的测试程序在末尾某处包含一个字符串 Hello world!,它也会很乐意尝试反汇编它。由你来识别这些垃圾,并忽略 ndisasm 对它所做的事情。