10
votes

I'm learning about x86 inline assembly programming.

I wanted to write mov ecx, FFFFFFBB, however the compiler isn’t recognizing it. How should hex numbers like that be written in inline assembler code?

4

4 Answers

20
votes

It depends on the flavour of your assembler.

  • AT&T: movl $0xFFFFFFBB, %ecx
  • Intel: mov ecx, 0FFFFFFBBh

FYI, AT&T syntax is used by assemblers such as the GNU Assembler, whereas NASM and most of others use Intel's one.

13
votes

See the tag wiki for links to assembler manuals, and lots of other stuff.


Different x86 assemblers support one or both of these syntaxes for hex constants:

  • 0xDEADBEEF: NASM (and compat), GNU as, FASM, MSVC inline asm (but not MASM), emu8086.
  • 0DEADBEEFh: NASM (and compat), FASM, MASM, TASM, emu8086.

DOS/Windows-only assemblers often only support the ...h syntax.
Portable assemblers typically support the 0x... syntax, or both.

Note the leading 0: Numeric constants always have to start with a decimal digit to distinguish them from symbol names. (How do I write letter-initiated hexadecimal numbers in masm code? is specifically about that, for trailing-h style.)

Also note that assemblers, like C compilers, can evaluate expressions at assemble time, so you can write foo & 0xF (if foo is an assembler constant, defined with foo equ 0xABC or something). You can even add/subtract from labels (which are link-time constants, not assemble-time), so stuff like mov eax, OFFSET label - 20 still assembles to a mov r32, imm32 mov-immediate instruction, just with a different 32-bit immediate.


From the NASM manual's section on constants:

Some examples (all producing exactly the same code):

    mov     ax,200          ; decimal 
    mov     ax,0200         ; still decimal 
    mov     ax,0200d        ; explicitly decimal 
    mov     ax,0d200        ; also decimal 
    mov     ax,0c8h         ; hex 
    mov     ax,$0c8         ; hex again: the 0 is required 
    mov     ax,0xc8         ; hex yet again 
    mov     ax,0hc8         ; still hex 
    mov     ax,310q         ; octal 
    mov     ax,310o         ; octal again 
    mov     ax,0o310        ; octal yet again 
    mov     ax,0q310        ; octal yet again 
    mov     ax,11001000b    ; binary 
    mov     ax,1100_1000b   ; same binary constant 
    mov     ax,1100_1000y   ; same binary constant once more 
    mov     ax,0b1100_1000  ; same binary constant yet again 
    mov     ax,0y1100_1000  ; same binary constant yet again

Most assemblers also allow character literals, like '0' for ASCII zero. Or even '0123' for four ASCII digits packed into a 32bit integer. Some support escape sequences (\n'), some (like YASM) don't. NASM only supports escape-sequences inside backquotes, not double quotes.


Other platforms:

ARM assembler: 0xDEADBEEF works.

I think 0x... is typical. the 0...h is mostly a DOS thing.

2
votes

It depends on your assembler, but a common notation for hex literals is 0FFFFFFBBh.

1
votes

Hex numbers are generally always represented with a leading 0x, so you'd use 0xFFFFFFBB.