Imagine you wrote this 10 years ago (before Intel MPX and the bnd0..bnd3 registers were even on a roadmap):
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
How can you assemble this with a current version of NASM? i.e. Does NASM (or YASM) have forward compatibility with new versions that support new register names?
Obviously this is easy to solve with search/replace inside a single file or project. But in theory, you could have a global variable name as part of a library ABI that you either export from NASM or need to import into NASM with extern ymm0. (External symbols have to be declared, so unrecognized register names never assemble to symbol references.)
NASM syntax is already unsuitable as a format for C compiler output on platforms which don't prefix symbol names with an _ or do some other kind of name mangling (e.g. Linux ELF). You can't compile a global int eax = 1;. This is why AT&T syntax uses %eax for register names. Discussion in comments on that answer is what inspired this question. Note that GAS doesn't need external symbols to be declared; unrecognized names are treated as symbols (even in .intel_syntax noprefix mode which uses a syntax similar to MASM).
Related: how does MASM handle forward source compatibility for new extensions?
Can you disable MPX support somehow?
YASM supports a CPU directive that lets you disable support for some mnemonics, but even disabling AVX support doesn't let you use ymm0 as a symbol name. (YASM 1.3.0 doesn't support AVX512 or MPX, so it can assemble code that uses those register names as symbols, but it does support AVX2.)
CPU Conroe
extern ymm0
I get yasm-CPU.asm:2: error: directive 'extern' requires an identifier parameter. Or with ymm0: dd 123, the error is yasm-CPU.asm:2: error: label or instruction expected at start of line
But AVX support is definitely disabled: assembling CPU Conroe / vmovaps xmm0, [edi] gives:
$ 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
(It says CPU 686 or similar for older disabled extensions. IDK why it doesn't say in CPU Sandybridge AVX. It seems that yasm is no longer well maintained. YASM 1.3.0 supports CPU Haswell and AVX2, but the docs don't mention it.)
The intent of this feature is to stop you from accidentally using SSE4 instructions in a function for SSSE3-or-lower CPUs, but apparently it doesn't help with this problem.
NASM's CPU directive seems to be similar, and also doesn't help at all:
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
Note that it does assemble extern ymm0 just fine, with or without a CPU directive, but as soon as you use it as an operand, you have a problem.