gpt4 book ai didi

c - 为什么 GCC pad 与 NOP 一起起作用?

转载 作者:行者123 更新时间:2023-11-30 16:53:05 27 4
gpt4 key购买 nike

我使用 C 语言已经有一段时间了,最​​近开始接触 ASM。当我编译程序时:

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

objdump 反汇编有代码,但 ret 之后为 nops:

...
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
...

据我所知,nops 什么都不做,而且 ret 之后甚至不会被执行。

我的问题是:为什么要麻烦呢? ELF(linux-x86) 无法处理任意大小的 .text 部分(+main)吗?

我很感激任何帮助,只是想学习。

最佳答案

首先,gcc并不总是这样做。填充由 -falign-functions 控制,由 -O2-O3 自动打开:

-falign-functions
-falign-functions=n

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-functions and -falign-functions=1 are equivalent and mean that functions will not be aligned.

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

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

Enabled at levels -O2, -O3.

这样做可能有多种原因,但 x86 上的主要原因可能是:

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.

(引自《优化汇编中的子程序语言”,作者:Agner Fog。)

编辑:以下是演示填充的示例:

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

当使用默认设置的 gcc 4.4.5 编译时,我得到:

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-functions给出:

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

关于c - 为什么 GCC pad 与 NOP 一起起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41033978/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com