2

I'm trying to compile the following using gcc -c main.s

.intel_syntax noprefix

.global main

main:
    push   ebp
    mov    ebp,esp
    sub    esp,0x10
    mov    DWORD PTR [ebp-0xc],0x0
    mov    eax,DWORD PTR [ebp+0xc]
    mov    eax,DWORD PTR [eax+0x4]
    mov    DWORD PTR [ebp-0x4],eax
    leave
    ret

And I get an error:

main.s:6: Error: operand type mismatch for `push'

What's the reason this isn't working?

melpomene
  • 84,125
  • 8
  • 85
  • 148
S. L.
  • 630
  • 8
  • 19
  • Try to write a C near-equivalent function in `foo.c` and compile it with `gcc -O -fverbose-asm -Wall -S foo.c` then look into the generated `foo.s` – Basile Starynkevitch Oct 07 '18 at 18:22
  • BTW, the assembler syntax varies from one `gcc` to the next one. In particular, the target and host operating systems are *very* important. Look into the output of `gcc -v` alone – Basile Starynkevitch Oct 07 '18 at 18:23
  • Are you on a 64-bit machine? – melpomene Oct 07 '18 at 18:28
  • @BasileStarynkevitch the code looks completely different, no wonder it won't compile.... – S. L. Oct 07 '18 at 18:37
  • @melpomene yes but I was able to compile other programs alread – S. L. Oct 07 '18 at 18:38
  • 1
    @BasileStarynkevitch: This is GAS intel-syntax. To get asm like what the OP has, use `gcc -masm=intel -S`. (I agree with your recommendation to use `-O1` at least to get less noisy code. [How to remove "noise" from GCC/clang assembly output?](https://stackoverflow.com/q/38552116), but the code in the question could be the output of `gcc -m32 -O0 -masm=intel`) – Peter Cordes Oct 07 '18 at 19:04

1 Answers1

7

From the Intel® 64 and IA-32 Architectures Software Developer’s Manual, 7.3.1.5 Stack Manipulation Instructions in 64-Bit Mode:

In 64-bit mode, the stack pointer size is 64 bits and cannot be overridden by an instruction prefix. In implicit stack references, address-size overrides are ignored. Pushes and pops of 32-bit values on the stack are not possible in 64-bit mode.

(Emphasis mine.)

push ebp tries to push a 32-bit register, which is not allowed in 64-bit mode.


This is 32-bit code (and would crash in 64-bit mode even if push ebp was encodeable), so you need to assemble it into a 32-bit executable. With gcc or clang, use

gcc -m32 -no-pie -fno-pie  main.s  -o my_prog

(The no-pie options are not necessary, but you probably want them to get a simpler position-dependent executable for 32-bit code.)

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
melpomene
  • 84,125
  • 8
  • 85
  • 148