为什么GCC垫功能与NOP指令? [英] Why does GCC pad functions with NOPs?

查看:261
本文介绍了为什么GCC垫功能与NOP指令?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直用C很短的一段时间,最近开始进入ASM。当我编译的程序:

I've been working with C for a short while and very recently started to get into ASM. When I compile a program:

int main(void)
  {
  int a = 0;
  a += 1;
  return 0;
  }

该objdump的反汇编有code,而RET后的NOP:

The objdump disassembly has the code, but nops after the ret:

...
08048394 <main>:
 8048394:       55                      push   %ebp
 8048395:       89 e5                   mov    %esp,%ebp
 8048397:       83 ec 10                sub    $0x10,%esp
 804839a:       c7 45 fc 00 00 00 00    movl   $0x0,-0x4(%ebp)
 80483a1:       83 45 fc 01             addl   $0x1,-0x4(%ebp)
 80483a5:       b8 00 00 00 00          mov    $0x0,%eax
 80483aa:       c9                      leave  
 80483ab:       c3                      ret    
 80483ac:       90                      nop
 80483ad:       90                      nop
 80483ae:       90                      nop
 80483af:       90                      nop
...

这是我所学到的NOP什么都不做,自从退役后甚至不被执行。

From what I learned nops do nothing, and since after ret wouldn't even be executed.

我的问题是:何必呢?无法ELF(Linux的x86)的任何大小的.text段(+主)工作?

My question is: why bother? Couldn't ELF(linux-x86) work with a .text section(+main) of any size?

我想AP preciate任何帮助,只是想学习。

I'd appreciate any help, just trying to learn.

推荐答案

首先, GCC 并不总是这样做。填充由<受控href=\"http://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html#Optimize-Options\"><$c$c>-falign-functions,

First of all, gcc doesn't always do this. The padding is controlled by -falign-functions, which is automatically turned on by -O2 and -O3:

-falign-功能结果
   -falign-功能= N

对齐函数的开始到下电源的两大于 N ,最多跳过 N 字节。例如,
   -falign-功能= 32 对齐功能,到下一个32字节边界,但 -falign-功能= 24 会对准下一个32字节边界仅
  如果这可以通过跳过23个字节或更少进行。

Align the start of functions to the next power-of-two greater than n, skipping up to n bytes. For instance, -falign-functions=32 aligns functions to the next 32-byte boundary, but -falign-functions=24 would align to the next 32-byte boundary only if this can be done by skipping 23 bytes or less.

-fno-ALIGN-功能 -falign-功能= 1 是等价的,表明函数不会对准。

-fno-align-functions and -falign-functions=1 are equivalent and mean that functions will not be aligned.

当n为2的幂有些汇编器只支持这个标志;在
  这种情况下,上舍入

Some assemblers only support this flag when n is a power of two; in that case, it is rounded up.

如果没有指定n或者为零,使用由机器决定的默认设置。

If n is not specified or is zero, use a machine-dependent default.

在级别-O2启用,-O3。

Enabled at levels -O2, -O3.

有可能是这样做的原因是多方面的,但在x86主要原因之一大概是这样的:

There could be multiple reasons for doing this, but the main one on x86 is probably this:

大多数处理器取在排列16字节或32字节的块的指令。有可能
  有利的是通过16对齐临界循环条目和子程序条目,以尽量减少
  16字节边界在code的数量。此外,请确保有一个关键循环条目或子程序入口后的前几个指令没有16字节边界。

Most processors fetch instructions in aligned 16-byte or 32-byte blocks. It can be advantageous to align critical loop entries and subroutine entries by 16 in order to minimize the number of 16-byte boundaries in the code. Alternatively, make sure that there is no 16-byte boundary in the first few instructions after a critical loop entry or subroutine entry.

(摘自汇编优化子程序报价
语言的瓦格纳雾。)

(Quoted from "Optimizing subroutines in assembly language" by Agner Fog.)

编辑:下面是一个说明填充一个例子:

edit: Here is an example that demonstrates the padding:

// align.c
int f(void) { return 0; }
int g(void) { return 0; }

在使用gcc 4.4.5使用默认设置编译,我得到:

When compiled using gcc 4.4.5 with default settings, I get:

align.o:     file format elf64-x86-64

Disassembly of section .text:

0000000000000000 <f>:
   0:   55                      push   %rbp
   1:   48 89 e5                mov    %rsp,%rbp
   4:   b8 00 00 00 00          mov    $0x0,%eax
   9:   c9                      leaveq 
   a:   c3                      retq   

000000000000000b <g>:
   b:   55                      push   %rbp
   c:   48 89 e5                mov    %rsp,%rbp
   f:   b8 00 00 00 00          mov    $0x0,%eax
  14:   c9                      leaveq 
  15:   c3                      retq   

指定 -falign-功能给出:

align.o:     file format elf64-x86-64

Disassembly of section .text:

0000000000000000 <f>:
   0:   55                      push   %rbp
   1:   48 89 e5                mov    %rsp,%rbp
   4:   b8 00 00 00 00          mov    $0x0,%eax
   9:   c9                      leaveq 
   a:   c3                      retq   
   b:   eb 03                   jmp    10 <g>
   d:   90                      nop
   e:   90                      nop
   f:   90                      nop

0000000000000010 <g>:
  10:   55                      push   %rbp
  11:   48 89 e5                mov    %rsp,%rbp
  14:   b8 00 00 00 00          mov    $0x0,%eax
  19:   c9                      leaveq 
  1a:   c3                      retq   

这篇关于为什么GCC垫功能与NOP指令?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆