Имя символа конфликтует с новыми именами имен в новых версиях 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.