I tried to convert and interpret C language code into assembly language with GCC -S option.
What is the difference between push %rbp and push rbp?
- 5,834
- 1
- 13
- 44
- 11
- 1
-
1`gcc -masm=intel` will use Intel syntax, the default is `-masm=att`. Pick whichever you find easier to read. See [How to remove "noise" from GCC/clang assembly output?](https://stackoverflow.com/q/38552116) – Peter Cordes May 29 '22 at 08:48
2 Answers
Both statements you gave do the same thing, the main difference is in the syntax.
There are 2 major syntax conventions for X86, the Intel convention and the AT&T convention.
See syntax comparison for details.
[UPD:] Just in case, duplicating the syntax information here:
| AT&T | Intel | |
|---|---|---|
| Parameter order | Source before the destination.movl $5, %eax |
Destination before source.mov eax, 5 |
| Parameter size | Mnemonics are suffixed with a letter indicating the size of the operands: q for qword, l for long (dword), w for word, and b for byte.addl $4, %esp |
Derived from the name of the register that is used (e.g. rax, eax, ax, al imply q, l, w, b, respectively).add esp, 4 |
| Sigils | Immediate values prefixed with a $, registers prefixed with a %. | The assembler automatically detects the type of symbols; i.e., whether they are registers, constants or something else. |
| Effective addresses | General syntax of DISP(BASE,INDEX,SCALE).movl mem_addr(%ebx,%ecx,4), %eax |
Arithmetic expressions in square brackets; additionally, size keywords like byte, word, or dword have to be used if the size cannot be determined from the operands.mov eax, [ebx + ecx*4 + mem_addr] |
- 5,834
- 1
- 13
- 44
-
1https://stackoverflow.com/tags/intel-syntax/info and https://stackoverflow.com/tags/att/info have similar info and syntax examples. Both linked from https://stackoverflow.com/tags/x86/info – Peter Cordes May 29 '22 at 08:47
In AT&T syntax, push rbp would be a push of a memory operand, with symbol name rbp, like if you compiled some C code that used long rbp; as a global variable.
rbp doesn't have a % so the assembler knows you aren't referring to the register of the same name; that's how AT&T syntax disambiguates this case. If you do want the register, you must use % like %rbp.
- Questions about AT&T x86 Syntax design
- What was the original reason for the design of AT&T assembly syntax?
rbp is an absolute addressing mode; normally you'd use pushq rbp(%rip) if you actually wanted to push the contents of a global. Push-memory with any other addressing mode looks like pushq (%rdi, %rsi, 8). In 32-bit code it is normal to access global variables with their bare symbol name, like mov foo, %eax to load from one.
But more likely you meant push rbp as the Intel-syntax version of push %rbp, pushing the register like a normal person.
gcc -masm=intel will use Intel syntax, the default is -masm=att. Pick whichever you find easier to read. See How to remove "noise" from GCC/clang assembly output?
For more details on syntax differences, see @hidefromkgb's answer, and:
- https://stackoverflow.com/tags/intel-syntax/info
- https://stackoverflow.com/tags/att/info
- Both are linked from https://stackoverflow.com/tags/x86/info which has lots of useful links to manuals and guides.
- 328,167
- 45
- 605
- 847
-
1@SepRoland: That answer is assuming `push rbp` is Intel-syntax (which is almost certainly what was intended, unless they just manually stripped the `%`). But good point, updated. – Peter Cordes May 31 '23 at 18:08