28

我用谷歌搜索,我看到大量轻率的回答基本上是在嘲笑提问者提出这样的问题。

Microchip免费提供一些源代码(我不想在这里发布它以防万一。基本上,谷歌AN937,点击第一个链接,有一个“源代码”链接及其压缩文件)。它在 ASM 中,当我看到它时,我开始对视。我想将其转换为类似于 ac 类型语言的东西,以便我可以跟进。因为诸如以下的行:

GLOBAL  _24_bit_sub
movf    BARGB2,w
subwf   AARGB2,f

可能很简单,但它们对我来说毫无意义。

那里可能有一些自动 ASM 到 C 的翻译器,但我能找到的只是人们说这是不可能的。坦率地说,它不可能是不可能的。两种语言都有结构,而且这种结构肯定可以翻译。

4

13 回答 13

44

您绝对可以从汇编程序制作 ac 程序。问题是它可能看起来不像你想的那样,或者它可能会。我的 PIC 生锈了,但使用另一个汇编器,说你有

add r1,r2

在 C 中可以说变成

r1 = r1 + r2;

可能更具可读性。您可能会失去对变量名称的任何感觉,因为值正在从内存跳转到寄存器并返回并且寄存器正在被重用。如果您谈论的是具有两个寄存器一个累加器和另一个寄存器的较旧图片,那么实际上可能更容易,因为变量大部分都在内存中,您查看地址,例如

q = mem[0x12];
e = q;
q = mem[0x13];
e = e + q;
mem[0x12] = e;

冗长而冗长,但很明显 mem[0x12] = mem[0x12] + mem[0x13];

这些内存位置可能是变量,它们不会像为具有一堆寄存器的处理器编译的 C 代码那样跳转。图片可能更容易找出变量,然后进行搜索和替换以在文件中命名它们。

您要查找的内容称为静态二进制翻译,不一定是从一个二进制文件到另一个(一个处理器到另一个)的翻译,但在这种情况下,是从 pic 二进制文件到 C 的翻译。理想情况下,您需要使用应用笔记并使用微芯片工具将其组装成二进制文件,然后进行翻译。您也可以进行动态二进制翻译,但您更不可能找到其中之一,而且它通常不会导致 C 而是一个二进制到另一个。有没有想过沃尔玛 15 美元的操纵杆与 pac-man 和 galaga 是如何工作的?来自街机的 rom 使用静态二进制翻译进行转换,优化和清理,并为手持设备中的新目标处理器编译了 C 或任何中间语言。

百万美元的问题,你能找到一张图片的静态二进制翻译器吗?谁知道呢,你可能必须自己写一个。猜猜这意味着什么,你写了一个反汇编器,而不是反汇编成本地汇编语法中的指令,比如 add r0,r1 你让你的反汇编器打印出 r0=r0+r1; 当你完成这个反汇编程序时,虽然你会非常了解 pic 汇编语言,以至于你不需要 asm 到 C 的翻译器。你有鸡和蛋的问题。

于 2009-09-04T02:20:06.987 回答
22

从已编译的程序中获取完全相同的源代码基本上是不可能的。但是反编译器一直是计算机科学的一个研究领域(例如dcc 反编译器,它是一个博士项目)。

有多种算法可用于对汇编代码进行模式匹配并生成等效的 C 代码,但很难以适用于所有输入的通用方式执行此操作。

您可能想查看Boomerang,了解最近在通用反编译器上的开源工作。

于 2009-09-04T02:02:07.557 回答
8

我曾经做过一个项目,其中知识产权的重要部分是一些用 x86 汇编代码编码的严肃算法。要将代码移植到嵌入式系统,该代码的开发人员(不是我)使用了一个名为 MicroAPL 的工具(如果我没记错的话):

我对该工具的表现感到非常非常惊讶。

另一方面,我认为这是“如果你不得不问,你买不起”类型的东西(他们一次性转换项目的价格范围可以计算到大约 4 条装配线)一美元)。

但是,您从供应商处获得的汇编例程通常被打包为可以从 C 调用的函数 - 所以只要例程执行您想要的(在您想要使用的处理器上),您可能只需要汇编它们并或多或少忘记它们——它们只是你从 C 调用的库函数。

于 2009-09-04T04:54:23.263 回答
8

无法 确定性地将汇编代码转换为 C。中断、自修改代码和其他低级事物除了 C 中的内联汇编外没有其他表示形式。汇编到 C 过程只能在一定程度上起作用。更不用说生成的 C 代码可能比实际阅读汇编代码更难理解......除非您使用它作为开始在 C 中重新实现汇编代码的基础,否则它有点有用。查看 IDA 的 Hex-Rays 插件。

于 2009-11-17T01:57:09.890 回答
7

肯定有一些自动化的 ASM 到 C 的翻译器,但我能找到的只是人们说这是不可能的。坦率地说,它不可能是不可能的。

不,这不对。编译会丢失信息:最终目标代码中的信息少于 C 源代码中的信息。反编译器不能神奇地从无到有地创建该信息,因此真正的反编译是不可能的。

于 2009-09-04T01:53:12.460 回答
7

是的,很可能将汇编代码逆向工程为高质量的 C。

我在一家 MicroAPL 工作,该公司生产一种名为 Relogix 的工具,用于将汇编代码转换为 C。在其他一篇文章中提到了这一点。

请查看我们网站上的示例:

http://www.microapl.co.uk/asm2c/index.html

于 2010-10-27T15:48:46.623 回答
4

这不是不可能,只是非常难。熟练的汇编和 C 程序员可能会这样做,或者您可以考虑使用Decompiler。其中一些在将 asm 转换为 C 方面做得很好,尽管您可能必须重命名一些变量和方法。

查看此站点以获取可用于 x86 架构的反编译器列表。

于 2009-09-04T02:03:07.073 回答
4

不容易。

除了可读性之外,C 相对于 ASM 的一大优势是它可以防止“聪明”的编程技巧。

您可以在汇编程序中执行许多没有直接 C 等效项或涉及 C 中曲折语法的事情。

另一个问题是大多数汇编程序本质上只有两种可互换的数据类型:字节和字。可能有一些语言结构来定义整数和浮点数等,但没有尝试检查内存是否按定义使用。因此,将 ASM 存储映射到 C 数据类型非常困难。

此外,所有的汇编存储本质上都是一个“结构”;存储按定义的顺序排列(与 C 不同,C 中的存储是在运行时随心所欲地进行排序的)。许多 ASM 程序依赖于确切的存储布局——为了在 C 中实现相同的效果,您需要将所有存储定义为单个结构的一部分。

还有很多被滥用的指令(在老式的 IBM manframes 上,LA、加载地址、指令通常用于执行简单的算术运算,因为它更快且不需要溢出寄存器)

虽然在技术上可能翻译成 C 语言,但生成的 C 语言代码的可读性不如被翻译的 ASM 代码。

于 2009-09-04T02:11:09.813 回答
3

看看这个:反编译器

反编译器是对执行与编译器相反的操作的计算机程序的名称。也就是说,它将包含相对较低抽象级别的信息(通常设计为计算机可读而不是人类可读)的文件转换为具有更高抽象级别的形式(通常设计为人类可读)。

于 2009-09-04T01:59:55.717 回答
3

我可以保证 99% 的保证,这种汇编语言没有现成的转换器,所以你需要编写一个。您可以简单地用 C 函数替换 ASM 命令来实现它:

movf    BARGB2,w -> c_movf(BARGB2,w);
subwf   AARGB2,f -> c_subwf(AARGB2,f);

这部分很简单:) 然后你需要实现每个功能。您可以将寄存器声明为全局变量以使事情变得简单。您也可以使用不是函数,而是#defines,如果需要调用函数。这将有助于处理参数/结果。

#define c_subwf(x,y) // I don't know this ASM, but this is some Substraction must be here

特殊情况是 ASM 指令/标签,我认为只能使用 #defines 进行转换。

当您达到一些特定于 CPU 的功能时,乐趣就开始了。这可以是带有堆栈操作的简单函数调用,一些特定的 IO/内存操作。更有趣的是程序计数器寄存器的操作,用于计算,或使用/计算滴答/延迟。

但是还有另一种方式,如果这个硬核发生。这也是硬核 :) 存在一种名为动态重新编译的技术。它在许多模拟器中使用。

您不需要重新编译 ASM,但想法几乎相同。您可以使用第一步中的所有#defines,但添加对所需功能的支持(增加 PC/Ticks)。您还需要为您的代码添加一些虚拟环境,例如内存/IO 管理器等。

祝你好运 :)

于 2009-09-18T08:56:20.127 回答
1

我认为拿起一本关于 PIC 汇编的书并学习阅读它会更容易。汇编程序通常很容易学习,因为它的级别很低。

于 2009-09-18T13:09:49.250 回答
0

将函数从 asm 转换为 C 很困难,但可以手动完成。使用反编译器转换整个程序会给你的代码可能无法理解,因为在编译过程中大部分结构都丢失了。如果没有有意义的变量和函数名称,生成的 C 代码仍然很难理解。

由于重复的模式和结构,基本程序的 C 编译器的输出(尤其是未优化的输出)可以翻译成 C。

于 2009-09-08T05:48:37.480 回答
0

查看asm2c

将 DOS/PMODEW 386 TASM 汇编代码转换为 C 代码的 Swift 工具

于 2017-02-27T21:28:32.707 回答