Search code examples
assemblyx86gnu-assembleratt

Can't size instruction


I was wondering why some assembly instructions can be inferred, but others cannot. For example, in the following program I have:

.globl main
main:
    push %rbp
    mov %rsp, %rbp
    mov $8, -8(%rbp)
    mov -8(%rbp), %rax
    pop %rbp
    ret

I get the following error:

stack.s:5: Error: no instruction mnemonic suffix given and no register operands; can't size instruction

However, if I change: the 5th line to:

movq $8, -8(%rbp)

It runs without error. How can all the other operations infer the size, but that particular instruction cannot?


Solution

  • The hint is in the message: "no register operands".

    All the other instructions have a register as an operand, and the assembler knows how large the registers are. So for instance, mov %rax, -8(%rbp) must be a quadword move (8 bytes) because %rax is a 64-bit register. Likewise, mov %eax, -8(%rbp), mov %ax, -8(%rbp), and mov %al, -8(%rbp) will be longword / word / byte moves (4 / 2 / 1 bytes). As such, the size suffix is optional for those instructions.

    But the immediate constant $8 has no inherent size, so the assembler has no way to know what size you wanted unless you tell it.