想象一下,你在 10 年前写了这个(在英特尔 MPX和bnd0
..bnd3
寄存器甚至在路线图上之前):
section .data
; define some globals which are part of an ABI so you can't just rename them
global bnd0 ; MPX bound register name conflict
bnd0: dd 123
global k0 ; AVX512 mask register name conflict
k0: dq 12345
您如何使用当前版本的 NASM 组装它? 即 NASM(或 YASM)是否与支持新寄存器名称的新版本具有前向兼容性?
显然,这很容易通过在单个文件或项目中搜索/替换来解决。但理论上,您可以将全局变量名作为库 ABI 的一部分,您可以从 NASM 导出或需要使用extern ymm0
. (必须声明外部符号,因此无法识别的寄存器名称永远不会汇编为符号引用。)
NASM 语法已经不适合作为 C 编译器输出的格式在不使用 an 前缀符号名称_
或进行一些其他类型的名称修饰(例如 Linux ELF)的平台上。您无法编译全局int eax = 1;
. 这就是 AT&T 语法%eax
用于寄存器名称的原因。对该答案的评论中的讨论激发了这个问题。请注意,GAS 不需要声明外部符号;无法识别的名称被视为符号(即使在.intel_syntax noprefix
使用类似于 MASM 的语法的模式下)。
相关:MASM 如何处理新扩展的前向源兼容性?
你能以某种方式禁用 MPX 支持吗?
YASM 支持一个CPU
指令,允许您禁用对某些助记符的支持,但即使禁用 AVX 支持也不允许您将ymm0
其用作符号名称。(YASM 1.3.0 不支持 AVX512 或 MPX,因此它可以汇编使用这些寄存器名称作为符号的代码,但它确实支持 AVX2。)
CPU Conroe
extern ymm0
我明白了yasm-CPU.asm:2: error: directive 'extern' requires an identifier parameter
。或者ymm0: dd 123
,错误是yasm-CPU.asm:2: error: label or instruction expected at start of line
但是绝对禁用 AVX 支持:组装CPU Conroe
/vmovaps xmm0, [edi]
给出:
$ yasm -Worphan-labels -felf32 yasm-CPU.asm
yasm-CPU.asm:2: warning: `vmovaps' is an instruction in CPU
yasm-CPU.asm:2: error: instruction expected after label
(它说CPU 686
或类似的旧禁用扩展。IDK 为什么它不说in CPU Sandybridge AVX
。似乎 yasm 不再得到很好的维护。YASM 1.3.0 支持CPU Haswell
and AVX2
,但文档没有提到它。)
此功能的目的是防止您在 SSSE3 或更低 CPU 的函数中意外使用 SSE4 指令,但显然它对解决此问题没有帮助。
NASM 的CPU
指令似乎是相似的,也根本没有帮助:
CPU 686
vmovaps xmm0, [edi]
extern ymm0
mov eax, ymm0
$ nasm -Worphan-labels -felf32 CPU.asm
CPU.asm:2: error: no instruction for this cpu level
CPU.asm:4: error: invalid combination of opcode and operands
请注意,无论extern ymm0
有没有指令,它都可以很好地组装CPU
,但是一旦将其用作操作数,就会出现问题。