Search code examples
linuxcompiler-errorsassemblygnu-assembler

Invalid instruction suffix for push when assembling with gas


When assembling a file with GNU assembler I get the following error:

hello.s:6: Error: invalid instruction suffix for `push'

Here's the file that I'm trying to assemble:

        .text
LC0:
        .ascii "Hello, world!\12\0"
.globl _main
_main:
        pushl   %ebp
        movl    %esp, %ebp
        subl    $8, %esp
        andl    $-16, %esp
        movl    $0, %eax
        movl    %eax, -4(%ebp)
        movl    -4(%ebp), %eax
        call    __alloca
        call    ___main
        movl    $LC0, (%esp)
        call    _printf
        movl    $0, %eax
        leave
        ret

What is wrong here and how do I fix it?

The problem is somewhat related to this question although errors and instructions in questions are different.


Solution

  • 64bit instructions

    By default most operations remain 32-bit and the 64-bit counterparts are invoked by the fourth bit in the REX prefix. This means that each 32-bit instruction has it's natural 64-bit extension and that extended registers are for free in 64-bit instructions

    movl $1,  %eax     # 32-bit instruction
    movq $1,  %rax     # 64-bit instruction
    
    pushl %eax         # Illegal instruction
    pushq %rax         # 1 byte instruction encoded as pushl %eax in 32 bits
    pushq %r10         # 2 byte instruction encoded as pushl preceeded by REX