Por que o código de máquina de saída do gcc tem instruções nop
Pergunta
Sempre que faço um objdump -d, sempre vejo o código asm com lotes de instruções nop (instruções que não fazem nada)
Por exemplo, pegue este mesmo programa:
#include <stdio.h>
#include <math.h>
int main()
{
printf("Hello World!\n");
printf("cos: %f\n", cos(1));
return 1;
}
O objdump para o exame tem 2 nops no final do ponto de entrada
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
E esse é apenas um de muitos exemplos, mas essa é a ideia.Por que o código C é compilado dessa maneira?Agradecemos antecipadamente.
Solução
Muitas vezes, eles são usados apenas para preencher os limites, para que as coisas subsequentes comecem em uma palavra ou limite novamente, já que o acesso a código arbitrário que não está alinhado nos limites de palavra é muito mais caro para a CPU.
Outras dicas
Os nop
s são adicionados para forçar o alinhamento da próxima função com o limite de 4 bytes.(observe que o endereço após o último nop
será 40047c, que é divisível por 4)