忘记密码   免费注册 查看新帖 | 论坛精华区

ChinaUnix.net

  平台 论坛 博客 认证专区 大话IT 视频 徽章 文库 沙龙 自测 下载 频道自动化运维 虚拟化 储存备份 C/C++ PHP MySQL 嵌入式 Linux系统
最近访问板块 发新帖
查看: 7723 | 回复: 2

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

论坛徽章:
1
申猴
日期:2014-02-11 14:50:31
发表于 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
发表于 2012-03-12 22:01 |显示全部楼层
查了很多资料,参考别人的例子,感觉都没法理解

有谁知道吗?

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

本版积分规则

  

北京皓辰网域网络信息技术有限公司. 版权所有 京ICP证:060528号 北京市公安局海淀分局网监中心备案编号:1101082001
广播电视节目制作经营许可证(京) 字第1234号 中国互联网协会会员  联系我们:
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP