Search code examples
cassemblyx86attgnu-assembler

Error: operand size mismatch for `lea' (seems like syntax error)


I'm trying to add a function S_0x804853E in an assembly file compiled by GCC. And i'm trying to assemble the file to execuable file. The complete assembly file is followed.

    .file   "simple.c"
    .intel_syntax noprefix
    .text
    .globl  main
    .type   main, @function
main:
.LFB0:
    .cfi_startproc
    push    ebp
    .cfi_def_cfa_offset 8
    .cfi_offset 5, -8
    mov ebp, esp
    .cfi_def_cfa_register 5
    sub esp, 16
    call    __x86.get_pc_thunk.ax
    add eax, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_
    mov DWORD PTR -4[ebp], 3
    mov eax, 0
    leave
    call S_0x804853E # note that this line is manually added.
    .cfi_restore 5
    .cfi_def_cfa 4, 4
    ret
    .cfi_endproc
.LFE0:
    .size   main, .-main
    .section    .text.__x86.get_pc_thunk.ax,"axG",@progbits,__x86.get_pc_thunk.ax,comdat
    .globl  __x86.get_pc_thunk.ax
    .hidden __x86.get_pc_thunk.ax
    .type   __x86.get_pc_thunk.ax, @function
__x86.get_pc_thunk.ax:
.LFB1:
    .cfi_startproc
    mov eax, DWORD PTR [esp]
    ret
    .cfi_endproc
.LFE1:
    .ident  "GCC: (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0"
    .section    .note.GNU-stack,"",@progbits
# note that codes below are manually added.
.type   S_0x804853E, @function
S_0x804853E:
    push ebp
    mov esp,ebp
    push ebx
    sub $0x4,esp
    call S_0x80485BB
    add $_GLOBAL_OFFSET_TABLE_,eax
    sub $0xC,esp
    lea S_0x80486B8,edx
    push edx
    mov eax,ebx
    call puts
    add $0x10,esp
    nop
    mov -0x4(ebp),ebx
    leave
    ret
.type   S_0x80485BB, @function
S_0x80485BB:
    mov (esp),eax
    ret

.section .rodata

S_0x80486B8:
    .byte 0x36
    .byte 0x00

I'm using commands below to assemble. And Errors followed.

$ gcc  -m32 -no-pie -nostartfiles simple.s -o simple                                                                                                  
simple.s: Assembler messages:                                                                         
simple.s:49: Error: operand size mismatch for `lea'                                                   
simple.s:55: Error: junk `(ebp)' after expression

I'm not very familiar with assembly. Apologize if the problem can be easily solved by google. But i failed to find any related explanations. Thanks for your help.


Solution

  • The main problem is that i mixed up the grammar of intel and AT&T. The codes generated from the tool are AT&T without operator suffix('b','l','w','q'). Compiling C code to AT&T and making up the operator suffix make sense. edited codes followed.

        .file   "simple.c"
        .text
        .globl  main
        .type   main, @function
    main:
    .LFB0:
        .cfi_startproc
        pushl   %ebp
        .cfi_def_cfa_offset 8
        .cfi_offset 5, -8
        movl    %esp, %ebp
        .cfi_def_cfa_register 5
        subl    $16, %esp
        call    __x86.get_pc_thunk.ax
        addl    $_GLOBAL_OFFSET_TABLE_, %eax
        movl    $3, -4(%ebp)
        movl    $0, %eax
        leave
        call S_0x804853E # note that this line is mannally added
        .cfi_restore 5
        .cfi_def_cfa 4, 4
        ret
        .cfi_endproc
    .LFE0:
        .size   main, .-main
        .section    .text.__x86.get_pc_thunk.ax,"axG",@progbits,__x86.get_pc_thunk.ax,comdat
        .globl  __x86.get_pc_thunk.ax
        .hidden __x86.get_pc_thunk.ax
        .type   __x86.get_pc_thunk.ax, @function
    __x86.get_pc_thunk.ax:
    .LFB1:
        .cfi_startproc
        movl    (%esp), %eax
        ret
        .cfi_endproc
    # note that codes below are mannally added
    .type   S_0x804853E, @function
    S_0x804853E:
        pushl %ebp
        movl %esp,%ebp
        pushl %ebx
        subl $0x4,%esp
        call S_0x80485BB
        addl $_GLOBAL_OFFSET_TABLE_,%eax
        subl $0xC,%esp
        lea S_0x80486B8,%edx
        pushl %edx
        movl %eax,%ebx
        call puts
        addl $0x10,%esp
        nop
        movl -0x4(%ebp),%ebx
        leave
        ret
    .type   S_0x80485BB, @function
    S_0x80485BB:
        movl (%esp),%eax
        ret
    
    .section .rodata
    
    S_0x80486B8:
        .byte 0x36
        .byte 0x00
    
    

    Codes can be assembled by gcc without warnings and errors.

    -------------------------split line for new edit----------------------

    Thanks for help from @Peter Cordes. It's unnecessary to explictly give all instructions the operand-size suffix. We use suffix only if the operand size of the instuction seems ambiguous without the declaration of size. EX:neither operand is a register.

    movl $4, -4(%ebp)