Имя символа конфликтует с новыми именами имен в новых версиях NASM?

Представьте, что вы написали это 10 лет назад (до Intel 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, либо импортируете в NASM с помощью extern ymm0. (Должны быть объявлены внешние символы, поэтому непризнанные имена регистров никогда не собираются на ссылки на символы.)

Синтаксис NASM уже не подходит в качестве формата вывода компилятора C на платформах, которые не префиксные имена символов с помощью _ или выполняют некоторые другие манипуляции с именами (например, 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 1.3.0 поддерживает CPU Haswell и AVX2 но в документах это не упоминается.)

Цель этой функции - помешать вам случайно использовать команды SSE4 в функции для процессоров SSSE3 или ниже, но, по-видимому, это не помогает с этой проблемой.


Директива 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, но как только вы используете его как операнд, у вас есть проблема.

Ответ 1

NASM позволяет вам префикс символа знака доллара $, чтобы он интерпретировался как символ, а не регистр или другое зарезервированное слово. Из Документация NASM:

3.1 Макет строки источника NASM

[...] Идентификатор также может иметь префикс с $, чтобы указать, что он предназначен для чтения как идентификатор, а не зарезервированное слово; таким образом, если какой-либо другой модуль, с которым вы связываетесь, определяет символ с именем eax, вы можете ссылаться на $eax в коде NASM, чтобы отличить символ от регистра. [...]

MASM обычно используется только в средах, где идентификаторы префиксов C-компиляторов с символами подчеркивания _, поэтому это не так много проблем с этим ассемблером. Однако у этого есть решение этой проблемы, но это в основном противоположность NASM. Вы можете использовать директиву OPTION NOKEYWORD, чтобы отключить зарезервированные слова по вашему выбору. Например, вы можете использовать OPTION NOKEYWORD:<eax>, чтобы вы могли использовать символ с именем eax. Конечно, это мешает вам использовать регистр EAX, поэтому он не является общим решением, как NASM.