0

Code sample:

int main(int argc, char *argv[]) {

        return 0;
}

Compile with command: gcc -m32 -g -o main main.c

This is the assembly from objdump:

080483db <main>:
int main(int argc, char *argv[]) {
 80483db:       55                      push   ebp
 80483dc:       89 e5                   mov    ebp,esp

        return 0;
 80483de:       b8 00 00 00 00          mov    eax,0x0
}
 80483e3:       5d                      pop    ebp
 80483e4:       c3                      ret    
 80483e5:       66 90                   xchg   ax,ax
 80483e7:       66 90                   xchg   ax,ax
 80483e9:       66 90                   xchg   ax,ax
 80483eb:       66 90                   xchg   ax,ax
 80483ed:       66 90                   xchg   ax,ax
 80483ef:       90                      nop

Why does gcc add all the xchg ax, ax and final nop there? I notice that without adding -m32, then those xchg ax, ax instructions are removed, but nop still presents:

0000000004004d6 <main>:
int main(int argc, char *argv[]) {
  4004d6:       55                      push   rbp
  4004d7:       48 89 e5                mov    rbp,rsp
  4004da:       89 7d fc                mov    DWORD PTR [rbp-0x4],edi
  4004dd:       48 89 75 f0             mov    QWORD PTR [rbp-0x10],rsi

        return 0;
  4004e1:       b8 00 00 00 00          mov    eax,0x0
}
  4004e6:       5d                      pop    rbp
  4004e7:       c3                      ret    
  4004e8:       0f 1f 84 00 00 00 00    nop    DWORD PTR [rax+rax*1+0x0]
  4004ef:       00
Amumu
  • 17,924
  • 31
  • 84
  • 131
  • They are not even reachable. Probably data. – Jean-François Fabre Dec 08 '16 at 07:28
  • 3
    Code is padded with "dummy" bytes to reach the next paragraph (16 byte) boundary `0x4004F0`. In 32-bit version `xchg ax,ax` is used as 2-byte padding, `nop` as 1-byte padding. – AnT stands with Russia Dec 08 '16 at 07:33
  • ... although the rationale behind it is not related to the legacy concept of "16-byte paragraph" (the latter being relevant only to old segmented-memory DOS platforms). – AnT stands with Russia Dec 08 '16 at 07:44
  • 1
    Your disassembler is being confusing. `66 90` is still just a NOP. The assembler uses a different choice of NOP-generation strategy in 64-bit code for various obscure reasons which don't matter since those NOPs will never be executed. – Peter Cordes Dec 08 '16 at 16:17

0 Answers0