assembly - ¿El nombre del símbolo entra en conflicto con los nuevos nombres de registro en las nuevas versiones de NASM?
x86 naming (1)
NASM le permite agregar un símbolo con un signo de dólar $
para que se interprete como símbolo en lugar de registrarse u otra palabra reservada. De la documentación de NASM :
3.1 Diseño de una línea fuente NASM
[...] Un identificador también puede tener el prefijo
$
para indicar que está destinado a leerse como un identificador y no como una palabra reservada; por lo tanto, si algún otro módulo con el que está vinculando define un símbolo llamadoeax
, puede hacer referencia a$eax
en el código NASM para distinguir el símbolo del registro. [...]
Normalmente, MASM solo se usa en entornos donde los compiladores de C prefijan los identificadores con guiones bajos _
, por lo que este no es un gran problema con ese ensamblador. Sin embargo, tiene una solución a este problema, pero es básicamente lo opuesto a NASM. Puede usar la directiva OPTION NOKEYWORD para deshabilitar las palabras reservadas de su elección. Por ejemplo, puede usar OPTION NOKEYWORD:<eax>
para que pueda usar un símbolo llamado eax
. Por supuesto, eso le impide usar el registro llamado EAX, por lo que no es una solución tan general como NASM.
Imagine que escribió esto hace 10 años (antes de que Intel MPX y los bnd0
.. bnd3
estuvieran incluso en una hoja de ruta):
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
¿Cómo se puede armar esto con una versión actual de NASM? es decir, ¿NASM (o YASM) tiene compatibilidad con versiones nuevas que admiten nuevos nombres de registros?
Obviamente, esto es fácil de resolver con búsqueda / reemplazo dentro de un solo archivo o proyecto. Pero, en teoría, podría tener un nombre de variable global como parte de una biblioteca ABI que usted exporta de NASM o necesita importar a NASM con extern ymm0
. (Los símbolos externos tienen que declararse, por lo que los nombres de registro no reconocidos nunca se ensamblan a referencias de símbolos).
La sintaxis de NASM ya no es adecuada como un formato para la salida del compilador de C en plataformas que no prefijan los nombres de símbolos con un _
o hacen algún otro tipo de creación de nombres (por ejemplo, Linux ELF). No puede compilar un global int eax = 1;
. Esta es la razón por la cual la sintaxis de AT & T usa %eax
para nombres de registros . La discusión en los comentarios sobre esa respuesta es lo que inspiró esta pregunta. Tenga en cuenta que GAS no necesita símbolos externos para ser declarados; los nombres no reconocidos se tratan como símbolos (incluso en el modo .intel_syntax noprefix
que utiliza una sintaxis similar a MASM).
Relacionado: ¿cómo gestiona MASM la compatibilidad de origen de las nuevas extensiones?
¿Puedes desactivar el soporte MPX de alguna manera?
YASM admite una directiva de CPU
que le permite desactivar el soporte para algunos mnemotécnicos, pero incluso deshabilitar la compatibilidad con AVX no le permite usar ymm0
como nombre de símbolo. (YASM 1.3.0 no admite AVX512 o MPX, por lo que puede ensamblar código que use esos nombres de registro como símbolos, pero sí admite AVX2).
CPU Conroe
extern ymm0
Recibo yasm-CPU.asm:2: error: directive ''extern'' requires an identifier parameter
. O con ymm0: dd 123
, el error es yasm-CPU.asm:2: error: label or instruction expected at start of line
Pero el soporte de AVX está definitivamente deshabilitado: ensamblando la CPU Conroe
/ vmovaps xmm0, [edi]
da:
$ 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
(Dice que la CPU 686
o similar para las extensiones discapacitadas más antiguas IDK por qué no dice in CPU Sandybridge AVX
. Parece que Yasm ya no está bien mantenido. YASM 1.3.0 es compatible con CPU Haswell
y AVX2
, pero los documentos no lo hacen mencionarlo.)
El objetivo de esta función es evitar que accidentalmente se utilicen las instrucciones SSE4 en una función para CPU SSSE3 o inferiores, pero aparentemente no ayuda con este problema.
La directiva de CPU
de NASM parece ser similar, y tampoco ayuda en absoluto:
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
Tenga en cuenta que ensambla extern ymm0
muy bien, con o sin una directiva de CPU
, pero tan pronto como lo usa como un operando, tiene un problema.