Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Disambiguate labels from register names in the Intel syntax

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?

like image 756
Rui Ueyama Avatar asked Aug 22 '19 09:08

Rui Ueyama


2 Answers

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

like image 56
kalehmann Avatar answered Nov 08 '22 04:11

kalehmann


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.

like image 20
Peter Cordes Avatar answered Nov 08 '22 04:11

Peter Cordes