繁体   English   中英

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

[英]Assembly - Are there any languages other than C and C++ that allow for interaction with Assembly using inline code?

我最近阅读了这份名为Embedded Systems/Mixed C 和 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);
}

And I was wondering if a similar interaction was possible in other high-level languages like Java, Python and others, or if this was only possible with C and C++.

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

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

Very high level languages like Python don't even have simple object-representations for numbers, eg an integer variable isn't just a 32-bit object, it has type info, and (in Python specifically) can be arbitrary length for large values . So even if a Python implementation did have inline-asm facilities, it would be a challenge to let you do anything to Python objects, except maybe for NumPy arrays which are laid out like C arrays.

可以从大多数高级语言调用本机机器代码函数(例如,从 C 或手写 asm 编译的库)——这对于编写某些类型的应用程序通常很重要。 例如,在 Java 中有 JNI(Java 本机接口)。 甚至 node.js JavaScript 也可以调用原生函数。 "Marshalling" args into a form that makes sense to pass to a C function can be expensive, depending on the high-level language and whether you want to let the C / asm function modify an array or just return a value.


不同语言的inline asm的不同forms

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

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

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


对于您展示的语法,无论是

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

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

您可以在 HolyC 中内联汇编。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM