免费注册 查看新帖 |

Chinaunix

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

说说今天碰到的alignment陷阱 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-12-09 22:59 |只看该作者 |倒序浏览
题目:将int v 复制到地址 0x12开始的地方。

失败:
int v = 0x55AA55AA;
int *ptr = (int *)0x12;
memcpy(ptr, &v, sizeof(v));

成功:
int v = 0x55AA55AA;
char *ptr = (char *)0x12;
memcpy(ptr, &v, sizeof(v));

编译器将memcpy完全优化掉了,并且根据ptr类型不同,优化出不同的代码。

论坛徽章:
0
2 [报告]
发表于 2009-12-09 23:17 |只看该作者
没明白,愿意继续听

论坛徽章:
0
3 [报告]
发表于 2009-12-09 23:32 |只看该作者

回复 #2 prolj 的帖子

现在没环境了,明天把汇编翻出来跟大家细说。

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
4 [报告]
发表于 2009-12-10 08:29 |只看该作者

回复 #1 小羊咪咪 的帖子

gcc? 优化掉是只不调用memcpy而是直接mov?
对0x12这个地址, 也会因为类型不同生成不同代码? i386?
求解……

论坛徽章:
0
5 [报告]
发表于 2009-12-10 09:10 |只看该作者
原帖由 小羊咪咪 于 2009-12-9 22:59 发表
题目:将int v 复制到地址 0x12开始的地方。

失败:
int v = 0x55AA55AA;
int *ptr = (int *)0x12;
memcpy(ptr, &v, sizeof(v));

成功:
int v = 0x55AA55AA;
char *ptr = (char *)0x12;
memcpy(pt ...

你的机器没有操作系统吗?

论坛徽章:
0
6 [报告]
发表于 2009-12-10 09:28 |只看该作者
ARMCC, 和操作系统无关。
=============================

这个是-O0也就是没开优化时的结果。
注意红色部分memcpy翻译成的汇编代码的不同。
出错的程序直接将memcpy变成了str命令,导致出现对齐错误。

之前以为用memcpy代替 *ptr = v; 就可以解决对齐的问题,
看来自己好多程序有这样的bug.

void test1()
{
    int v = 0x55AA55AA;
[0xe59f0008]   ldr      r0,0x00006154 ; = #0x55aa55aa
    int *ptr = (int *)0x12;
[0xe3a01012]   mov      r1,#0x12
    memcpy((char *)ptr, &v, sizeof(v));   
[0xe5810000]   str      r0,[r1,#0]
}
[0xe12fff1e]   bx       r14
[0x55aa55aa]   dcd      0x55aa55aa  .U.U

=============================

void test2()
{
[0xe92d401c]   stmfd    r13!,{r2-r4,r14}
    int v = 0x55AA55AA;   
[0xe59f001c]   ldr      r0,0x00006180 ; = #0x55aa55aa
[0xe58d0004]   str      r0,[r13,#4]
    char *ptr = (char *)0x12;   
[0xe3a04012]   mov      r4,#0x12
    memcpy((char *)ptr, &v, sizeof(v));   
[0xe3a02004]   mov      r2,#4
[0xe08d1002]   add      r1,r13,r2
[0xe1a00004]   mov      r0,r4
[0xebffe7e3]   bl       __rt_memcpy
}
[0xe8bd401c]   ldmfd    r13!,{r2-r4,r14}
[0xe12fff1e]   bx       r14
[0x55aa55aa]   dcd      0x55aa55aa  .U.U

[ 本帖最后由 小羊咪咪 于 2009-12-10 09:30 编辑 ]

论坛徽章:
0
7 [报告]
发表于 2009-12-10 09:28 |只看该作者
:wink:
我想问下到底是用什么平台的!
看不懂上面的汇编!

[ 本帖最后由 wolfired 于 2009-12-10 09:35 编辑 ]

论坛徽章:
324
射手座
日期:2013-08-23 12:04:38射手座
日期:2013-08-23 16:18:12未羊
日期:2013-08-30 14:33:15水瓶座
日期:2013-09-02 16:44:31摩羯座
日期:2013-09-25 09:33:52双子座
日期:2013-09-26 12:21:10金牛座
日期:2013-10-14 09:08:49申猴
日期:2013-10-16 13:09:43子鼠
日期:2013-10-17 23:23:19射手座
日期:2013-10-18 13:00:27金牛座
日期:2013-10-18 15:47:57午马
日期:2013-10-18 21:43:38
8 [报告]
发表于 2009-12-10 10:08 |只看该作者
应该是编译器不恰当的优化导致了错误

论坛徽章:
0
9 [报告]
发表于 2009-12-10 10:16 |只看该作者
memcpy的参数类型是void *吧?如果memcpy不是做为编译器内置的函数的话,应该不至于做如此优化吧?
如果memcpy是做为库提供的话,那在memcpy中应该没法知道参数的类型的啊
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP