【问题标题】:Run dynamically generated assembly in C (GNU/Linux)在 C (GNU/Linux) 中运行动态生成的程序集
【发布时间】:2023-09-18 12:02:01
【问题描述】:

我正在用 C 编写一个概念验证 JIT 编译器,目前它正在生成汇编代码字符串。 C 中的内联汇编功能仅处理在编译时已知的字符串文字,因此我不能使用它来运行我在运行时生成的代码。

我已经阅读了有关使用 mmap() 在运行时执行生成的机器代码的信息,但我想尽可能避免使用机器代码。

有人知道任何解决方案吗?我曾想过将其写入文件并在所述文件上调用汇编器和链接器,但这会很麻烦而且很慢。

【问题讨论】:

  • 所以你是说你生成汇编源代码?为什么不自己生成机器码?
  • @DrewMcGowen 我不希望这样做,因为它的可读性较差,更难测试,而且时间至关重要,所以如果我想尽可能避免重构。虽然看起来我可能不得不这样做。
  • 有很多库可以用来发布程序集。 gnu-lightningllvm, ...

标签: c assembly compiler-construction jit machine-code


【解决方案1】:

我认为最终要成为“JIT”,您需要对时间敏感,这意味着生成机器代码。您可以尝试放入一些调试代码来生成要运行的机器代码和要验证的汇编代码,运行汇编程序将汇编语言中的机器代码与您直接生成的机器代码进行比较,然后使用它来调试/验证机器代码(如果可能的话,有时汇编程序想做他们自己的事情,而不是你想让他们做的事情)。

【讨论】:

  • 同时生成机器代码以运行,并生成程序集以进行调试/测试,这是一个好主意。我想这就是我要做的。非常感谢。
【解决方案2】:

我所做的是生成 C/C++/Fortran 代码,即时编译,将其链接到 DLL,然后动态加载 DLL,所有这些操作最多只需要几秒钟的时间。 除了生成 ASM 之外,您也可以这样做。 当您需要生成代码的速度以及所生成语言的代码(和运行时库)的灵活性时,这是一种非常有效的技术。

【讨论】:

  • 我决定使用机器码选项,但我发现这是一个非常有趣的想法,我将在未来的项目中考虑它。您是否知道任何相关的文章/教程等?
  • @AlexJ136:文章?要学习的关键内容是 1)如何编写 DLL(任何示例都可以),2)如何“脱壳”以在程序的控制下运行编译器+链接器,以及 3)如何加载 DLL 并获取该过程解决了它的导出问题。