15

Everytime I do an objdump -d I always see the asm code with batches of nop instructions (instructions that do nothing)

For example take this same program:

#include <stdio.h>
#include <math.h>

int main()
{
    printf("Hello World!\n");
    printf("cos:  %f\n", cos(1));
    return 1;
}

The objdump for exampe has 2 nops at the end of the entry point

0000000000400450 <_start>:
400450: 31 ed                   xor    %ebp,%ebp
400452: 49 89 d1                mov    %rdx,%r9
400455: 5e                      pop    %rsi
400456: 48 89 e2                mov    %rsp,%rdx
400459: 48 83 e4 f0             and    $0xfffffffffffffff0,%rsp
40045d: 50                      push   %rax
40045e: 54                      push   %rsp
40045f: 49 c7 c0 00 06 40 00    mov    $0x400600,%r8
400466: 48 c7 c1 70 05 40 00    mov    $0x400570,%rcx
40046d: 48 c7 c7 34 05 40 00    mov    $0x400534,%rdi
400474: e8 bf ff ff ff          callq  400438 <__libc_start_main@plt>
400479: f4                      hlt    
40047a: 90                      nop
40047b: 90                      nop 

And that is just one of many examples but you get the idea. Why is the C code compiled this way? Thanks in Advance.

sigjuice
  • 28,661
  • 12
  • 68
  • 93
PuercoPop
  • 6,707
  • 4
  • 30
  • 40

2 Answers2

18

The nops are added to force the next function align to the 4-byte boundary. (notice that the address following the last nop will be 40047c which is divisible by 4)

kennytm
  • 510,854
  • 105
  • 1,084
  • 1,005
  • On x86_64, I've also noticed a 4-byte nop in the middle of a function (just before a `call`): `0f 1f 40 00 nop DWORD PTR [rax+0x0]` Any idea what that's good for? Happens at `-O3`. – Kerrek SB Jul 09 '13 at 12:37
  • 1
    @Kerrek if I recall correctly, that tells the processor to clear its cache and reload it with the data at the pointed address. In that case, the processor would wipe its cache with the data at `[rax]` (which I assume is the address the call jumps to). This allows the processor to begin to reload its cache with correct data before the jump. – Cole Tobin Jul 30 '13 at 21:04
8

Very often those are just used to do padding so that subsequent stuff starts on a word or boundary again, as access to arbitrary code that is not aligned on word boundaries is much more expensive for the cpu.

Heiko Rupp
  • 30,426
  • 13
  • 82
  • 119