Search code examples
assemblyx86-64gnu-assemblerattimmediate-operand

Enter a decimal number explicitly in assembly


I find myself often not immediately recognizing if a number is in decimal or in hex (if the hex number doesn't have a prefix or letters). For example, from a previous question a number like 0000000000400078 and not sure which it is.

Is there a way to explicitly specify a decimal number with a prefix in x86_64? For example:

 mov     %rsp,       %rbp
 movb    $0x16,      -1(%rbp)
 movb    $0d22       -2(%rbp) # <-- something like this
 movb    $0b10110,   -3(%rbp)

I know that doing movb $22, -2(%rbx) works, but is there a way to explicitly prefix/suffix it so that we know it's a decimal?


Solution

  • No, not for GAS. https://sourceware.org/binutils/docs/as/Integers.html - A decimal integer starts with a non-zero digit followed by zero or more digits (0123456789).

    Hex numbers on screen in debuggers or objdump output sometimes omit a 0x, like 0000000000400078 which is hex. You have to know from context that addresses are almost always printed in hex.

    In asm source code the rules are simple, unambiguous, and not context-sensitive. In GAS source code, if you don't see an explicit base override, it's decimal. This applies for $123 immediates, 123(%reg) displacements, .set xyz, 123 assembler-directive operands, .long 123 pseudo-instructions to emit bytes / dwords into the output, and every other context where GAS lets you write a numeric literal.

    It also applies to all ISAs that GAS supports - note that this part of the GAS manual is not under one specific ISA. And of course for x86-64 it applies in both .intel_syntax noprefix mode and in AT&T mode.


    Different assemblers may support different ways to write numbers in different bases, at least for non-decimal bases; this answer is for GAS, the GNU assembler.

    There are a few assemblers, notably the nasty obsolete DOS debug.exe, where every numeric literal is taken as hex. debug.exe doesn't support decimal at all. As @old_timer likes to point out, assembly syntax is defined by the assembler, not by the ISA.

    The majority of x86 assemblers (NASM, MASM, GAS, Go-asm) default to decimal when there's no explicit modifier. Some may have explicit-decimal syntax you can use if you want, but GAS doesn't.