Tiny C Generated Compiler Code Highlights Additional (Unnecessary?) NOP and JMP

Can someone explain why this code:

#include <stdio.h>

int main()
{
  return 0;
}

when compiling with tcc using tcc code.c creates this asm:

00401000  |.  55               PUSH EBP
00401001  |.  89E5             MOV EBP,ESP
00401003  |.  81EC 00000000    SUB ESP,0
00401009  |.  90               NOP
0040100A  |.  B8 00000000      MOV EAX,0
0040100F  |.  E9 00000000      JMP fmt_vuln1.00401014
00401014  |.  C9               LEAVE
00401015  |.  C3               RETN

I suppose that

00401009  |.  90   NOP

perhaps exists for some memory alignment, but what about

0040100F  |.  E9 00000000     JMP fmt_vuln1.00401014
00401014  |.  C9              LEAVE

I mean, why does the compiler insert this nearest jump that jumps to the next command , will LEAVE be executed anyway?

I am on 64-bit Windows generating a 32-bit executable using TCC 0.9.26.

+6
source share
2 answers

JMP Epilogue

JMP , , . 0.9.27 TCC :

"return" - ( ) .

? , . , JMP , , ret. JMP- , } ( ). , return, . , JMP

:

int main(int argc, char *argv[])
{
  if (argc == 3) {
      argc++;
      return argc;
  }
  argc += 3;
  return argc;
}

:

  401000:       55                      push   ebp
  401001:       89 e5                   mov    ebp,esp
  401003:       81 ec 00 00 00 00       sub    esp,0x0
  401009:       90                      nop
  40100a:       8b 45 08                mov    eax,DWORD PTR [ebp+0x8]
  40100d:       83 f8 03                cmp    eax,0x3
  401010:       0f 85 11 00 00 00       jne    0x401027
  401016:       8b 45 08                mov    eax,DWORD PTR [ebp+0x8]
  401019:       89 c1                   mov    ecx,eax
  40101b:       40                      inc    eax
  40101c:       89 45 08                mov    DWORD PTR [ebp+0x8],eax
  40101f:       8b 45 08                mov    eax,DWORD PTR [ebp+0x8]

  ; Jump to common function exit point. This is the `return argc` inside the if statement
  401022:       e9 11 00 00 00          jmp    0x401038

  401027:       8b 45 08                mov    eax,DWORD PTR [ebp+0x8]
  40102a:       83 c0 03                add    eax,0x3
  40102d:       89 45 08                mov    DWORD PTR [ebp+0x8],eax
  401030:       8b 45 08                mov    eax,DWORD PTR [ebp+0x8]

  ; Jump to common function exit point. This is the `return argc` at end of the function 
  401033:       e9 00 00 00 00          jmp    0x401038

  ; Common function exit point
  401038:       c9                      leave
  401039:       c3                      ret

0.9.27 return argc if ( epilogue). , return argc . , return argc, JMP, , , .


NOP Prologue

NOP . - , Windows (, Portable Executable) TCC . < 4096 ( ), :

401000:       55                      push   ebp
401001:       89 e5                   mov    ebp,esp
401003:       81 ec 00 00 00 00       sub    esp,0x0

sub esp,0 . , ( 0). , , 0x0 SUB , . 9 . , a >= 4096 . 4096 - :

char somearray[4096] 

, 10- :

401000:       b8 00 10 00 00          mov    eax,0x1000
401005:       e8 d6 00 00 00          call   0x4010e0

TCC , proog 10 WinPE. , TCC . , , . , , TCC 10 , . 10 .

, < 4096 9 . NOP 10 . , >= 4096 , EAX, __chkstk < > .

+10

TCC , , . , main, , ret. IDK, , JMP , .

: TCC Tiny C Compiler. , . sub esp, 0: -, TCC , 0 . , main() . TCC sub esp,0 0 . ( ), imm32, , imm8. - 32- .

, , - . ++ - asm ( gcc/clang/icc , ). , asm ; gcc- - , . . Basile C?


JMP ( @MichaelPetch) : TCC ( ) , JMP .

NOP . , , /, . ( NOP - , , NOP , , TCC NOP , , , , , NOP. , gcc/clang/icc, -.)

@MichaelPetch , TCC , 10 , ( , , imm32). Windows ESP/RSP (4096 ), - 10 9 NOP. , asm.


xor-zero EAX ( , , , mov eax,0), . xor-zeroing // x86- , , , x86.

main:
    xor eax,eax
    ret

- EBP, pop ebp , leave , , ESP = EBP, mov esp,ebp leave . pop ebp - 1 , , leave, 2 3. (http://agner.org/optimize/, tag wiki.) , gcc. ; , ESP pop ebx - .


TCC , ( ) . , - TCC / MB/ ( C) gcc3.2 -O0, ~ 9 P4.

, TCC braindead: , , , , , JMP ( sub esp, 0).

+2

All Articles