在新的NASM版本中,符号名称与新的寄存器名称冲突吗? [英] Symbol name conflicts with new register names in new NASM versions?

查看:143
本文介绍了在新的NASM版本中,符号名称与新的寄存器名称冲突吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

想象一下您是10年前写的(在英特尔MPX bnd0之前. bnd3寄存器甚至在路线图上):

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

如何将其与当前版本的NASM组合?,即NASM(或YASM)与支持新寄存器名称的新版本具有向前兼容性吗?

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?

显然,这很容易通过在单个文件或项目中进行搜索/替换来解决.但是从理论上讲,您可以将全局变量名称作为库ABI的一部分,您可以从NASM导出,或者需要使用extern ymm0 import 导入到NASM中. (必须声明外部符号,因此无法识别的寄存器名称永远不会汇编为符号引用.)

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语法已经不适合作为在平台上使用C编译器输出的格式,这些平台不使用_作为符号名称的前缀,也不进行其他类型的名称处理(例如Linux ELF).您不能编译全局int eax = 1;. 这就是AT& amp ; T语法使用%eax作为寄存器名称.关于该答案的评论中的讨论是促使这个问题产生的原因.请注意,GAS不需要声明外部符号.无法识别的名称将被视为符号(即使在.intel_syntax noprefix模式下也使用类似于MASM的语法).

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).

相关:MASM如何处理新扩展的前向源兼容性?

Related: how does MASM handle forward source compatibility for new extensions?

您可以通过某种方式禁用MPX支持吗?

YASM支持CPU指令使您可以禁用对某些助记符的支持,但是即使禁用AVX支持也不能使您使用ymm0作为符号名称. (YASM 1.3.0不支持AVX512或MPX,因此它可以汇编将那些寄存器名称用作符号的代码,但它确实支持AVX2.)

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

我得到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

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

但是绝对禁止AVX支持:组装CPU Conroe/vmovaps xmm0, [edi]会给出:

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    

(对于较旧的禁用扩展名,它说CPU 686或类似名称.IDK为什么不说in CPU Sandybridge AVX.似乎yasm不再得到很好的维护.YASM1.3.0支持CPU HaswellAVX2,但是文档没有提及.)

(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.)

此功能的目的是阻止您在SSSE3或更低版本的CPU的功能中意外使用SSE4指令,但这显然对解决此问题没有帮助.

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的CPU指令似乎很相似,也根本没有帮助:

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

请注意,无论是否有CPU指令,它都能很好地汇编extern ymm0,但是一旦将其用作操作数,就会遇到问题.

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.

推荐答案

使用NASM,您可以在符号前面加上美元符号$,以便将其解释为符号,而不是寄存器或其他保留字.从 NASM文档:

NASM lets you prefix a symbol with a dollar sign $ so that it's interpreted as symbol rather than register or other reserved word. From the NASM documentation:

3.1 NASM源代码行的布局

[...]标识符也可以带有$前缀,以表示它应作为标识符而不是保留字来读取;因此,如果要链接的其他模块定义了名为eax的符号,则可以在NASM代码中引用$eax来区分该符号与寄存器. [...]

3.1 Layout of a NASM Source Line

[...] An identifier may also be prefixed with a $ to indicate that it is intended to be read as an identifier and not a reserved word; thus, if some other module you are linking with defines a symbol called eax, you can refer to $eax in NASM code to distinguish the symbol from the register. [...]

MASM通常仅在C编译器的标识符带有下划线_的前缀环境中使用,因此,对于该汇编器而言,这并不是什么大问题.但是,它确实有解决此问题的方法,但基本上与NASM的相反.您可以使用OPTION NOKEYWORD指令禁用您选择的保留字.例如,您可以使用OPTION NOKEYWORD:<eax>,以便可以使用名为eax的符号.当然,这会阻止您使用名为EAX的寄存器,因此它不像NASM那样通用.

MASM is normally only used in environments where C compilers prefix identifiers with underscores _, so this isn't as big of an issue with that assembler. However it does have a solution this problem, but it's basically the opposite of NASM's. You can use the OPTION NOKEYWORD directive to disable reserved words of your choice. For example you can use OPTION NOKEYWORD:<eax> so that you can use a symbol named eax. Of course that prevents you from using the register named EAX, so it's not as general solution as NASM's.

这篇关于在新的NASM版本中,符号名称与新的寄存器名称冲突吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆