这取决于汇编程序。
我认为对于大多数人来说,注册名称优先,因此call rdx 将始终为 RIP=RDX,而不检查是否存在同名标签(或外部符号)。AT&T 语法 call *%rdx,而不是 AT&T call rdx。
一些汇编程序有语法可以消除歧义,但不同的汇编程序没有标准语法。
例如对于 NASM,这是 Symbol name conflicts with new register names in new NASM versions? 的副本,您可以使用 $eax 来引用名称为 eax 的符号/标签,而不是寄存器。
对于 Euroassembler,您可以将 : 后缀到名称上,以强制将其解释为符号,而不是注册,例如 call rdx:。 (https://euroassembler.eu/eadoc/#SymbolName),
使用 GAS,您可以使用 .intel_syntax prefix 代替 .intel_syntax noprefix,因此寄存器名称仍需要 %rdx。
.intel_syntax 没有操作数意味着.intel_syntax prefix。
GAS 的 Intel 语法可能有点落后于 AT&T 语法的二等公民。在%rdx 是寄存器,rdx 是符号的 AT&T 语法中显然不存在这个问题。
.intel_syntax # prefix is the default
rdx:
call rdx # call rel32
call %rdx # call reg
.intel_syntax noprefix
call rdx # call reg
# I don't know how to write call rel32 to the label with noprefix
然后我们可以在 AT&T 语法中进行反汇编,以便更加清楚/明确地了解我们得到的内容。
$ gcc -c gas-symbol.s && objdump -d -Matt gas-symbol.o
0000000000000000 <rdx>:
0: e8 fb ff ff ff callq 0 <rdx>
5: ff d2 callq *%rdx
0000000000000007 <with_noprefix>:
7: ff d2 callq *%rdx
对于整个文件,您通常不希望这样,但您可以切换到 .att_syntax 或 .intel_syntax prefix 用于一行或块,然后切换回正常的 .intel_syntax noprefix。