【问题标题】:Can GAS assemble on non-Intel systems if Intel syntax is used?如果使用 Intel 语法,GAS 可以在非 Intel 系统上组装吗?
【发布时间】:2023-03-06 22:48:02
【问题描述】:

如果我在非英特尔系统上进行汇编,我可以将英特尔语法与 GAS (GNU Assembler) 一起使用吗?

本质上,我是starting out 从事汇编编程,虽然我在高级语言方面有多年经验,但我想选择一个适用于 x86 和 ARM 的汇编程序。可能还有其他架构,但目前这不是迫切需要。

到目前为止,我对 NASM 很满意,但我还需要 ARM,所以 GAS 似乎是一个不错的候选者。没有写过任何复杂的东西,但我对 AT&T 和 Intel 语法同样持开放态度。

如果我选择 Intel 语法,我唯一不确定是否可以使用 GAS 进行跨架构编程?

我意识到指令集自然会有所不同,但我只想选择一种工具来涵盖这两种架构 - 我的想法是,如果随着时间的推移我需要第三个工具,那么学习和维护的工具将会减少我从第一天开始就在 GAS 中做所有事情。

直观地说,我会说使用 Intel 语法而不是 AT&T 在 ARM 或其他非 Intel 架构上组装程序应该没有任何障碍,因为 GAS 可能会构建 AST,然后发出特定于架构的代码,而不管前端的语法,但不幸的是,我无法访问 ARM 系统来试用它,尽管如此,我还是非常想与更多知识渊博的人确认它。谢谢。

编辑:我想出了一个类比,也许可以更清楚地说明我的想法。假设有人学会了在 Linux 上有效地使用 vim 来使用 Python,那么所有这些知识都会很容易地转移到 Mac 上,以便使用 Objective-C 进行开发。

不用说,Python 和 Objective-C 是两种截然不同的语言,但工具知识(本例中为 vim)仍然很有用。

如果有一天这个人需要在 Windows 上开发 Java,同样的情况仍然成立,程序员将能够在第三个系统上使用 vim 或衍生产品。

最终,语言之间的实际差异,Python、Obj-C 和 Java,自然会使任何与工具相关的问题相形见绌,但是当某人刚刚开始时,使用同一个工具来满足多种不同需求的想法是相当不错的很吸引人。

这就是我正在考虑的那种可重用性。

【问题讨论】:

  • 请注意,每个架构都有自己的指令集和语法。 ARM 上没有“Intel 语法”或“AT&T 语法”之类的东西。如果您编写汇编代码,则必须为 x86 和 ARM 编写完全不同的代码,无论您使用什么汇编程序。
  • Arm 组装没有 Intel 或 AT&T 语法的概念。出于向后兼容性的原因,GAS 不使用 x86 汇编的标准表示法;对于 Arm 没有类似的东西,GAS 使用 Arm 手册规定的语法
  • 是的,GAS 可用于 ARM 组装。事实上,除了 Keil 和 Go 附带的汇编器之外,它几乎是唯一常用的 ARM 汇编器。但请注意,ARM 汇编语法与 Intel 和 AT&T 语法完全不同。
  • binutils 能够支持多种架构,但是一次一个,当您编译一组二进制工具时,您选择了目标。另一方面,llvm 是或可以是为许多体系结构构建一组二进制文件的另一种方式,但它们没有目标特定的汇编语言,它们有一个用于字节码的汇编语言,现在可以从字节码生成对象。不确定我是否知道另一个是跨架构、构建时间或运行时。从汇编器的角度来看并没有太大的价值,因为从一个到另一个的交叉很少,不足以值得。
  • @AtticusStonestrom 非常有道理!在某种程度上(我在这里半开玩笑)如果我的问题从字面上理解,真正的答案是否定的,如果使用英特尔语法,GAS 无法在非英特尔系统上组装:-)其背后的原因不是 GAS 本身的任何限制。

标签: assembly x86 arm gnu-assembler


【解决方案1】:

你的一些直觉是对的。 Gas 确实支持multiple architectures,并且有像assembler directives 这样的核心功能,可以让你在Gas 的架构端口之间传递一些工作知识。某些命令行概念将被共享;其他的会因架构端口维护者当时的想法而有所不同。

您问题的其他方面,特别是 AT&T 语法与英特尔语法的问题,不适合您提出的问题。我更喜欢将这些视为 x86 的方言,挑战在于学习指令集。你对改变架构的要求是更根本的;你每次都会学习一种新的“语言”,像 .balign 这样的 Gas 指令就像这些语言之间唯一常见的标点符号一样。

Gas 确实需要为您要定位的每个架构构建一个单独的版本。在任何单个系统上,您可能都在“本地”操作,就像您想为当前机器编写汇编程序一样。这不是使用 Gas 的唯一方法,因此如果您手头没有 Arm 机器,“试用”它的一种方法是安装交叉汇编器(例如,在 Ubuntu https://packages.ubuntu.com/focal/binutils-arm-linux-gnueabi 上)。

【讨论】:

  • 请注意,.align(以及其他一些指令)实际上在架构和平台之间的语义上有所不同!详情请参阅手册。
  • 哈 - 我选择了一个尽可能糟糕的例子来展示常识。让我们继续将答案升级为.balign
  • @JamesGreenhalgh - 我在问题的末尾进行了编辑以更好地表达自己,但我相信我们都有相同的想法。英特尔和 AT&T 仅被视为仅适用于 x86 的方言的概念是一个有趣的概念,它让我对这个主题进行了更彻底的思考。我还怀疑,当我真正开始使用 ARM 时,事情会变得更加清晰,在这种情况下,我一定会在此处发表评论,无论何时发生。
  • @Terry 请注意,确实存在在所有平台上使用相同语法的汇编程序(Plan 9/Go 汇编程序是我所知道的唯一一个)。然而,这是一个难得的选择。通常,每个平台都有不同的语法。
  • 方言这个词在我脑海中浮现,因为它在 GCC 手册中用于描述编译器的 -masm=dialect 选项(其中方言可以是 intelatt)。 gcc.godbolt.org/z/nzvYWr 之类的内容可能会帮助您直观地了解 x86 和 Arm 的两种“方言”之间的区别。
【解决方案2】:

我想选择一个同时适用于 x86 和 ARM 的汇编器

你到底想做什么?

  1. 在 ARM 计算机上编写程序(采用 x86 语法!),然后在 x86 PC 上运行,或者在 x86 PC 上编写程序(采用 ARM 语法!),然后在 ARM CPU 上运行?
  2. 编写可在 ARM 和 x86 PC 上运行的汇编程序?

如果答案是 1.:

小型设备(例如 WLAN 路由器或智能手机)中的许多 CPU 都是 ARM CPU。但是,您想在具有 x86 CPU 的 PC 上为此类设备开发程序。

您所做的是使用带有“目标”ARM 和“主机”x86 的 GAS 版本。这意味着 GAS 在 x86 CPU 上运行,但为 ARM CPU 生成代码。

但是,您的“源代码”(汇编程序)必须是 ARM 汇编程序。

据我所知,GAS 仅支持 ARM CPU 的一种语法变体;没有什么比 ARM 的“AT&T”语法更好的了。

如果您有一台 ARM 计算机并且想在其上编写 x86 程序,您当然可以使用带有“目标”x86 和“主机”ARM 的 GAS 版本。如果“target”是 x86,GAS 支持“AT&T”和“Intel”语法,独立于“host”。

如果答案是 2.:

这行不通!

在汇编语言中,一条汇编指令通常代表 CPU 的一条指令。而不同的CPU架构,指令完全不同,汇编代码也完全不同。

这里是 x86 和 ARM 的示例程序:

Intel CPU, Intel syntax         ARM (non-Thumb) CPU
-----------------------         -------------------
mov eax, 4
mov ebx, 1                      ldr r0, =1
mov ecx, offset myText          ldr r1, =myText
mov edx, 6                      ldr r2, =6
int 0x80                        svc #0x900004

shr edi, 6
add eax, edi                    add r0, r0, r6, lsr #6

                                ldr r5, =someVariable
add [someVariable], eax         ldr r7, [r5]
                                add r7, r0
                                str r7, [r5]

你可以看到指令没有1:1的关系:

x86 上的指令add [someVariable], eax 需要 ARM 上的 4 条指令; ARM 上的指令add r0, r0, r6, lsr #6 需要 x86 上的 2 条指令。

【讨论】:

  • 感谢您的回答,但是是的,我只考虑第一种情况。我不知何故错误地认为英特尔语法仅适用于基于英特尔的 CPU,而 AT&T 也可以在英特尔和其他地方使用。但我现在明白了自己的困惑。
猜你喜欢
  • 2019-03-23
  • 2023-02-26
  • 1970-01-01
  • 2020-12-25
  • 1970-01-01
  • 1970-01-01
  • 2012-03-10
  • 1970-01-01
  • 2019-10-31
相关资源
最近更新 更多