简介:我正在查看汇编代码来指导我的优化,并在将int32添加到指针时看到许多符号或零扩展.
void Test(int *out, int offset)
{
out[offset] = 1;
}
-------------------------------------
movslq %esi, %rsi
movl $1, (%rdi,%rsi,4)
ret
Run Code Online (Sandbox Code Playgroud)
起初,我认为我的编译器在添加32位到64位整数时遇到了挑战,但我已经用Intel ICC 11,ICC 14和GCC 5.3证实了这种行为.
这个帖子证实了我的发现,但不清楚是否需要符号或零扩展.仅当尚未设置高32位时,才需要此符号/零扩展.但x86-64 ABI难道不够聪明吗?
我有点不愿意将所有指针偏移更改为ssize_t,因为寄存器溢出会增加代码的缓存占用空间.
在main使用gcc -g -o program -m32 program.c64位机器(运行ubuntu 14.04)编译的函数(简单玩具程序)的序言中,我得到以下反汇编:
dump of assembler code for function main:
0x08048e24 <+0>: push %ebp
0x08048e25 <+1>: mov %esp,%ebp
0x08048e27 <+3>: and $0xfffffff0,%esp
...
Run Code Online (Sandbox Code Playgroud)
<+3>指令的目的是什么?也就是说,为什么要$esp指向一个16对齐的地址?
我读过的,因为它是为"业绩原因"做不同的地方,但我仍然不知道什么是在性能得到这个16字节对齐提高了特殊情况.或者,无论如何,选择这个的原因是什么.
编辑:我想我以误导的方式写了这个问题.我没有询问为什么处理器使用16字节对齐的内存更快地处理事情,这在文档中随处可见.我想要知道的是,强制执行16字节对齐比仅让程序员在需要时自己对齐堆栈更好.我问这个是因为根据我的汇编经验,堆栈实施有两个问题:只有少于1%的执行代码才有用(所以其他99%实际上是开销); 它也是一个非常常见的错误来源.所以我想知道它最终是如何得到回报的.虽然我对此仍有疑问,但我接受了彼得的回答,因为它包含了我原来问题的最详细答案.