I'm wondering how to distinguish label names from register names in some instructions in the Intel syntax. For example, call rdx
usually means an indirect jump, but what if we have a label rdx
in the same assembly file? I believe it could be interpreted as a direct jump to rdx
. Is there any notation to tell the assembler which is which?
Is there any notation to tell the assembler which is which?
This depends on the assembler you use. There is no common syntax to do so.
However some assemblers have features to distinguish labels from reserved words. For example the section "3.1 Layout of a NASM Source Line" in the nasm documentation states, that you can prefix your label with a $
to distinguish it from the register:
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
It depends on the assembler.
I think for most, register names take precedence, so call rdx
would always be RIP=RDX, without checking for the existence of a label (or extern symbol) of the same name.
AT&T syntax call *%rdx
, not AT&T call rdx
.
Some assemblers have syntax to disambiguate, but there's no standard syntax across different assemblers.
e.g. for NASM, this is a duplicate of Symbol name conflicts with new register names in new NASM versions? where you can use $eax
to refer to a symbol / label with the name eax
, instead of the register.
For Euroassembler you can postfix a :
onto a name to force it to be interpreted as a symbol, not register, like call rdx:
. (https://euroassembler.eu/eadoc/#SymbolName),
With GAS, instead of .intel_syntax noprefix
, you could use .intel_syntax prefix
so %rdx
is still required on register names.
.intel_syntax
without an operand means .intel_syntax prefix
.
GAS's Intel-syntax is maybe a bit of a 2nd-class citizen behind AT&T syntax. This problem obviously doesn't exist in AT&T syntax where %rdx
is the register and rdx
is the symbol.
.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
Then we can disassemble in AT&T syntax just to be extra clear / unambiguous about what we got.
$ 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
You probably wouldn't want this normally for a whole file, but you could switch to .att_syntax
or .intel_syntax prefix
for one line or block then switch back to normal .intel_syntax noprefix
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With