我有一个名为.p2align
的汇编指令,它由gcc
从C程序源生成。
据我所知,对齐访问速度比未对齐访问速度快,asm
程序也不会自动对齐内存位置或优化内存访问,因此您必须这样做。
我无法真正阅读.p2align 4,,15
,尤其是最后一部分15
。
正如许多文档所报告的那样,明显gcc
生成2 ,
而不是1 {2}的事实;我得到的是这段asm
以这样的方式对齐记忆,即每个位置占据2 ^ 4位,这意味着16位,所以我认为可以说WORD
是16在这种情况下有点长。
现在15
可能意味着什么?这是多少比特?计数是从0
开始,所以“实际”数量是16而不是15?
编辑:
我刚刚将相同的C源转换为32位和64位asm代码,内存始终以相同的方式与同一指令.p2align 4,,15
对齐。那是为什么?
答案 0 :(得分:20)
.p2align
指令记录在案here。
第一个表达式是所需的2次幂字节对齐。 .p2align 4
焊盘在16字节边界上对齐。 .p2align 5
- 32字节边界等
第二个表达式是用作填充的值。对于x86,最好留下这个并让汇编程序选择,因为有一系列指令是有效的无操作。在某些对齐指令中,您会看到0x90
,这是NOP
指令。
最后一个表达式是填充的最大字节数 - 如果对齐需要更多,则跳过指令。在这种情况下 - 4,,15
- 它什么都不做,因为15
是产生16字节对齐所需的最大字节数。
答案 1 :(得分:1)
指令名称的p2部分来自gas可能是英特尔P-II CPU建议的原始实现,以提供循环体代码的条件对齐。正如Agner Fog所解释的那样,最初的目的是确保第一次取指令获得足够的代码来开始解码。
还存在与循环流检测器的交互,如果在循环的顶部和底部使用额外的指令缓存行片段,则可能无法启动。对齐是有条件的,以避免消耗超过必要的存储器,并且在执行填充字节的情况下避免过多的时间要求。 gcc根据mtune目标设置做出不同的对齐选择。
有些目标设置了2个对齐指令,例如进行无条件的8字节对齐和条件32字节对齐。 选择各种nop模式的原因是为了最小化在执行填充流的情况下(当执行从上面进入循环时)所花费的时间。例如,将寄存器复制到自身的前缀指令可以比单字节nops更快地消耗代码字节。这与此线程中最初提到的情况没有区别。 因此,部分混淆可能来自此对齐指令,其具有与设置数据对齐无关的特征,尽管该指令也用于此目的。