【问题标题】:Is it possible to convert C/C++ source code to assembly?是否可以将 C/C++ 源代码转换为程序集?
【发布时间】:2013-11-13 17:54:01
【问题描述】:

是否有可能以某种方式将简单的 C 或 C++ 代码(简单的意思是:将一些 int 作为输入,打印一些依赖于该 int 作为输出的简单形状)转换为汇编语言?如果没有,我将手动执行,但由于我将为英特尔 8080 等处理器执行此操作,因此似乎有点乏味。你能以某种方式自动化这个过程吗?

另外,如果有办法,与仅手动翻译相比,输出汇编文件源代码有多好(如:优雅)?

【问题讨论】:

  • 有些程序被称为编译器 ;-)。以gcc -S 为例。
  • 将一种语言翻译成另一种语言的过程称为编译,我们通常将C/C++编译成二进制,但是编译成另一种语言,无论是汇编还是java也是可以的,大多数C/C++工具链允许您直接编译为程序集,但是在 GCC 和 Clang 中,这是使用 -S 标志完成的。
  • 一般来说,我们主要进行减少抽象的编译,并且从低级语言编译到高级语言,在从低级语言编译到高级语言时有时被称为“反编译”语言,从中创建了这个低级翻译。然而,这通常意味着丢失所有或大部分抽象,因为这些抽象在从高到低的编译过程中通常会丢失。
  • 最后一点,当从高级语言编译到低级语言时,禁用调试符号和优化可能是个好主意,以使输出程序集更适合人类读者。

标签: c++ c assembly


【解决方案1】:

大多数编译器都允许您生成汇编输出。举几个明显的例子,Clang 和 gcc/g++ 使用 -S 标志,而 MS VC++ 使用 -Fa 标志这样做。

一些编译器不直接支持这一点(例如,如果内存服务 Watcom 不支持)。我所见过的那些让你生成一个目标文件,然后包含一个反汇编程序,它可以从目标文件生成一个汇编语言文件。我不太记得了,但如果这是您需要使用 Digital Mars 编译器执行的操作,我不会感到惊讶。

对于习惯于编写汇编语言的人来说,大多数编译器的输出通常看起来至少有些不雅,尤其是在像 x86 这样的 CPU 上,它有很多现在真正通用的寄存器,但历史上一直有更具体的含义。例如,如果某段代码既需要指针又需要计数器,人们可能会将指针放在 ESI 或 EDI 中,而将计数器放在 ECX 中。编译器可能很容易反转这些。这工作很好,但是经验丰富的汇编语言程序员无疑会发现使用 ESI 作为指针和 ECX 作为计数器更具可读性。

【讨论】:

  • 非常感谢。关于您提到的寄存器,我有一个问题:正如我所说,我需要一个汇编代码,以便它可以在 Intel 8080 或类似的“古老”处理器下工作。有什么方法可以模拟(或以某种方式“告诉”)编译器它正在编译哪种 CPU,这样我最终得到的汇编代码不使用 8080 或 8086 中根本不存在的寄存器?跨度>
  • @Straightfw:从实际的角度来看,您所能做的(可能)只是找到一个针对(例如)8086 的旧编译器。大多数编译器都分为一个前端,专门用于源语言和专用于目标处理器的后端,因此(理论上)您可以编写一个针对相关处理器的后端,但这通常并不重要。对于一个非常有限的处理器来说确实是相当困难的。
  • @Straightfw:不仅仅是缺少几个寄存器。最实际的是,all 32 位和 64 位寄存器在 80386 之前丢失。而long 仍然是 32 位类型。这意味着你的编译器必须能够做一些现代编译器不关心的事情,只使用 16 位寄存器来合成 32 位操作。
【解决方案2】:

看看gcc -S:

gcc -S hello.c # outputs hello.s file

至少保持部分 gcc 兼容性的其他编译器也可以接受此标志。例如,LLVM 的 clang 就可以。

【讨论】:

  • 请注意,使用 gcc,汇编输出是 AT&T 风格的。
  • 我认为英特尔语法有一个开关。
  • -masm switch 选择 asm 风格,貌似我没用过。
  • 另外,我不确定 GCC 是否会生成将在 8080 上运行的代码!
  • 您可能是对的...您可以针对特定的 CPU 使用 -march 标志,但您可以获取的最早可能是 i386
【解决方案3】:

嗯,是的,有这样一个程序。它被称为“编译器”

回答您的编辑:输出的优雅取决于您的编译器的优化。通常编译器不会生成我们人类称之为“优雅”的代码。

【讨论】:

  • 它在运行时效率方面会很优雅,但不会很容易被人类阅读:)
【解决方案4】:

这里的大多数人都是对的,但似乎错过了关于 8080 的说明(难怪,它不在标题中:)。然而,谷歌一如既往地来救援 - 寻找compiler for 8080 会产生一些不错的结果,如下所示:

其中大部分都相当陈旧,可能维护不善。你也可以试试 8085 很相似

【讨论】:

  • 非常感谢您解决我的问题的小但非常重要的细节:)
【解决方案5】:
(by simple I mean: taking some int as input, printing some simple shapes dependent on 
 that int as output) to assembly language?

查看 x86 编译器的输出不会很有帮助,因为输入和输出是由 C 或 C++ 库完成的。 8080 没有这样的库,因此您必须为某些特定硬件开发自己的 I/O 例程。这是很多很多额外的工作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-05-20
    • 1970-01-01
    • 1970-01-01
    • 2011-03-25
    • 2012-01-05
    • 2017-06-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多