汇编 - 除了 C 和 C++ 之外,还有其他语言允许使用内联代码与汇编交互吗?

Leo*_*rka 1 c c++ java assembly inline-assembly

我最近阅读了这篇名为Embedded Systems/Mixed C and Assembly Programming 的文档

它主要涉及 C 和 C++ 如何允许用户通过称为内联汇编的技术使用汇编代码,该技术看起来像这样:

#include<stdio.h>
 
void main() {
 
   int a = 3, b = 3, c;
 
   asm {
      mov ax,a
      mov bx,b
      add ax,bx
      mov c,ax
   }
 
   printf("%d", c);
}
Run Code Online (Sandbox Code Playgroud)

我想知道在其他高级语言(如 Java、Python 和其他语言)中是否可以进行类似的交互,或者是否只能使用 C 和 C++。

Pet*_*des 5

是的,D、Rust、Delphi 和许多其他提前编译的语言都有某种形式的内联汇编。

Java 没有,通常从可移植二进制文件(如 Java 的 .class 字节码或 C# 的 CIL)进行 JIT 编译的大多数其他语言也没有。 Java中的代码注入/汇编内联?.

像 Python 这样的高级语言甚至没有简单的数字对象表示,例如整数变量不仅仅是一个 32 位对象,它还具有类型信息,并且(特别是在 Python 中)对于大值可以是任意长度. 因此,即使一个Python实现也有内联汇编设施,这将是让你做任何事情的Python对象,这与NumPy阵列也许除外挑战布局像C数组。

可以从大多数高级语言调用本机机器代码函数(例如从 C 编译的库或手写 asm)——这对于编写某些类型的应用程序通常很重要。例如,在 Java 中有 JNI(Java 本机接口)。甚至 node.js JavaScript 也可以调用原生函数。“编组” args 到一个有意义的形式传递给 C 函数可能会很昂贵,这取决于高级语言以及您是想让 C/asm 函数修改数组还是只返回一个值。


不同语言中不同形式的内联汇编

通常,它们不像您使用的那样是 MSVC 的低效形式(这会强制存储/重新加载输入和输出)。更好的设计,比如以 GNU C 内联 asm 为模型的 Rust 可以使用寄存器。例如,像 GNU C 一样,asm("lzcnt %1, %0" : "=r"(leading_zero_count) : "rm"(input));让编译器选择一个输出寄存器,并为输入选择寄存器或内存寻址模式。

(但更好的是使用类似_lzcnt_u32__builtin_clz编译器知道的操作的内在函数,仅内联 asm 用于编译器没有内在函数的指令,或者如果您想以某种方式微优化循环 。https://gcc .gnu.org/wiki/DontUseInlineAsm )

有些(如 Delphi)通过类似于函数调用的“调用约定”进行输入,在寄存器中带有 args,不能完全自由地混合 asm 和高级代码。所以它更像是一个带有固定输入的 asm 块,以及一个特定寄存器中的一个输出(加上副作用),编译器可以像函数一样内联。


对于像你展示的那样工作的语法,要么

  • 你必须手动保存/恢复你asm 块中使用的每个寄存器(除非你包装一个大循环,否则对性能来说真的很糟糕——显然 Borland Turbo C++ 就是这样)
  • 或者编译器必须理解每一条指令才能知道它可能写入哪些寄存器(MSVC 就是这样)。Rust 的内联 asm 的设计说明/讨论提到了D 或 MSVC 编译器的这一要求,以实现有效的 DSL(领域特定语言),以及有多少额外的工作,特别是对于新 ISA 的可移植性。

请注意,MSVC 对内联 asm 的特定实现非常脆弱和笨拙,以至于它不能在带有寄存器 args 的函数中安全工作,这意味着根本不支持 x86-64 或 ARM/AArch64,其中标准调用约定使用寄存器 args . 相反,它们基本上为每条指令提供了内在指令,包括像 那样的特权指令,invlpg从而可以在 Visual C++ 中编写内核(例如 Windows)。(其他编译器希望您将其asm()用于此类事情的地方)。Windows 几乎可以肯定有几个部分写在单独的 .asm 文件中,例如中断和系统调用入口点,也许还有一个上下文切换函数,它必须加载一个新的堆栈指​​针,但具有良好的内在支持,您不需要 asm,如果你相信你的编译器能自己制作出足够好的 asm。

  • 不要遗漏汇编语言;您可以在汇编语言源文件中编写内联汇编。 (3认同)