Конфликты имен символов с новыми именами регистров в новых версиях 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). Вы не можете скомпилировать global 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 и 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.