免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 9347 | 回复: 2
打印 上一主题 下一主题

gcc 栈对齐问题 [复制链接]

论坛徽章:
1
申猴
日期:2014-02-11 14:50:31
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2012-03-12 11:50 |只看该作者 |倒序浏览
5可用积分
int test_ret()
{
  int ret=1;
  if(ret==0)
    return 1;
}

int main()
{
   int ret;
   ret=test_ret();
}

gcc -mpreferred-stack-boundary=4 -g -o test15 test15.cpp

环境:
gcc -v
使用内建 specs。
目标:i386-redhat-linux
配置为:../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-libgcj-multifile --enable-languages=c,c++,objc,obj-c++,java,fortran,ada --enable-java-awt=gtk --disable-dssi --enable-plugin --with-java-home=/usr/lib/jvm/java-1.4.2-gcj-1.4.2.0/jre --with-cpu=generic --host=i386-redhat-linux
线程模型:posix
gcc 版本 4.1.2 20080704 (Red Hat 4.1.2-4

汇编:
Dump of assembler code for function main():
0x08048384 <main()+0>:  lea    0x4(%esp),%ecx
0x08048388 <main()+4>:  and    $0xfffffff0,%esp
0x0804838b <main()+7>:  pushl  -0x4(%ecx)
0x0804838e <main()+10>: push   %ebp
0x0804838f <main()+11>: mov    %esp,%ebp
0x08048391 <main()+13>: push   %ecx
0x08048392 <main()+14>: sub    $0x10,%esp
0x08048395 <main()+17>: call   0x804835a <test_ret()>
0x0804839a <main()+22>: mov    %eax,-0x8(%ebp)
0x0804839d <main()+25>: mov    $0x0,%eax
0x080483a2 <main()+30>: add    $0x10,%esp
0x080483a5 <main()+33>: pop    %ecx
0x080483a6 <main()+34>: pop    %ebp
0x080483a7 <main()+35>: lea    -0x4(%ecx),%esp
0x080483aa <main()+38>: ret  

Dump of assembler code for function test_ret():
0x0804835a <test_ret()+0>:      push   %ebp
0x0804835b <test_ret()+1>:      mov    %esp,%ebp
0x0804835d <test_ret()+3>:      sub    $0x14,%esp
0x08048360 <test_ret()+6>:      movl   $0x1,-0x4(%ebp)
0x08048367 <test_ret()+13>:     cmpl   $0x0,-0x4(%ebp)
0x0804836b <test_ret()+17>:     jne    0x8048377 <test_ret()+29>
0x0804836d <test_ret()+19>:     mov    $0x1,%eax
0x08048372 <test_ret()+24>:     mov    %eax,-0x14(%ebp)
0x08048375 <test_ret()+27>:     jmp    0x804837e <test_ret()+36>
0x08048377 <test_ret()+29>:     call   0x8048354 <test1()>
0x0804837c <test_ret()+34>:     jmp    0x8048381 <test_ret()+39>
0x0804837e <test_ret()+36>:     mov    -0x14(%ebp),%eax
0x08048381 <test_ret()+39>:     leave  
0x08048382 <test_ret()+40>:     ret

从man gcc下面可以看出:
-mpreferred-stack-boundary
Attempt to keep the stack boundary aligned to a 2 raised to num byte boundary.  If -mpreferred-stack-boundary is not specified, the default is 4 (16 bytes or 128bits).
On Pentium and PentiumPro, "double" and "long double" values should be aligned to an 8 byte boundary (see -malign-double) or suffer significant run time performance penalties.  On Pentium III, the Streaming SIMD Extension (SSE) data type "__m128" may not work properly if it is not 16 byte aligned.

To ensure proper alignment of this values on the stack, the stack boundary must be as aligned as that required by any value stored on the stack.  Further, every function must be generated such that it keeps the stack aligned.  Thus calling a function compiled with a higher preferred stack boundary from a function compiled with a lower preferred stack boundary will most likely misalign the stack.  It is recommended that libraries that use callbacks always use the default setting.

但从汇编结果来看,在进入test_ret()时,esp并没有像gcc那样描述的,进行了16字节对齐

为什么呢?

论坛徽章:
1
申猴
日期:2014-02-11 14:50:31
2 [报告]
发表于 2012-03-12 22:01 |只看该作者
查了很多资料,参考别人的例子,感觉都没法理解

有谁知道吗?

论坛徽章:
1
程序设计版块每日发帖之星
日期:2015-09-23 06:20:00
3 [报告]
发表于 2012-03-16 14:06 |只看该作者
你的例子太简单,gcc知道不对齐也可以工作,所以优化了。你用SSE 数据类型测试,obj会不同
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP