首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >GCC函数填充值

GCC函数填充值
EN

Stack Overflow用户
提问于 2010-12-20 09:45:51
回答 3查看 1.2K关注 0票数 6

每当我在启用优化的情况下编译C或C++代码时,d GCC都会将函数与16字节的边界对齐(在IA-32上)。如果函数小于16个字节,则GCC会用一些字节来填充它,这些字节似乎根本不是随机的:

代码语言:javascript
复制
19:   c3                      ret
1a:   8d b6 00 00 00 00       lea    0x0(%esi),%esi

它似乎总是8d b6 00 00 00 00 ...8d 74 26 00

函数填充字节有意义吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2010-12-20 10:42:21

填充是由组装者创建的,而不是由gcc创建的。它只看到一个.align指令(或等效指令),并不知道要填充的空间是在函数内部(例如循环对齐)还是函数之间,因此它必须插入某种类型的NOP。现代x86汇编器使用尽可能大的NOP操作码,目的是在填充用于循环对齐的情况下花费尽可能少的周期。

就我个人而言,我非常怀疑对齐作为一种优化技术。我从来没有见过它有多大的帮助,而且它肯定会因为极大地增加总代码大小(和缓存利用率)而受到伤害。如果您使用-Os优化级别,那么默认情况下它是关闭的,所以没有什么需要担心的。否则,您可以使用适当的-f选项禁用所有路线。

票数 7
EN

Stack Overflow用户

发布于 2010-12-20 10:04:17

指令lea 0x0(%esi),%esi只是将%esi中的值加载到%esi中-它是无操作(或NOP),这意味着如果它被执行,它将不起作用。

这恰好是一条单指令,6字节NOP。8d 74 26 00只是同一指令的4字节编码。

票数 2
EN

Stack Overflow用户

发布于 2011-09-10 00:42:30

汇编器首先看到一条.align指令。因为它不知道这个地址是否在函数体中,所以它不能输出空的0x00字节,而必须生成NOP (0x90)。

但是:

代码语言:javascript
复制
lea    esi,[esi+0x0] ; does nothing, psuedocode: ESI = ESI + 0

执行所需的时钟周期少于

代码语言:javascript
复制
nop
nop
nop
nop
nop
nop

如果这段代码碰巧落在函数体中(例如,循环对齐),那么lea版本会快得多,同时仍然“什么都不做”。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4486301

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档