user-0 提问: ARM64 structure 对齐问题

回复:
user: user-1
content: source code:   11 __attribute__ ((__section__(".init.data"))) uint32_t fw_ver = 0;    20 struct spinlock {                                                  21         uint32_t lock;                                                22 }__attribute__((packed));        78 __attribute__ ((__section__(".init.data"))) spinlock_t dbg_lock = {.lock = 0};  79 __attribute__ ((__section__(".init.data"))) uint32_t dbg_rd_idx = 0;   ldscript: 153 SECTIONS { 154 .init.data : { 155     156 } > INIT_DATA 157 }  system.map: 482  .init.data     0x000000000003fc00       0x10  483                 0x000000000003fc00                fw_ver 484                 0x000000000003fc08                dbg_lock 485                 0x000000000003fc0c                dbg_rd_idx  我想LZ想问的是为什么dbg_lock的地址是08而不是04，对吧。毕竟fw_ver的大小是4字节，那么04就可以了。  其实我倒不奇怪dbg_lock的地址是08。因为总的来说，不管计算机是怎样的架构，访问word是最快最有效的，这点LZ应该赞同吧。64位机器字长8字节，那么比8字节小的4字节整数，自然都是对其到8的倍数地址上访问时最有效的。  我更好奇的是，为什么dbg_rd_idx的地址是0c。按照上述的推理，dbg_rd_idx的地址应该是10，这样才更有效。仔细想想，觉得是__attribute__((packed))起了作用。  我有个想法，给fw_ver加上__attribute__((aligned (4)))，不知LZ能否帮忙试试，告诉我结果是怎样的。

user: user-2
content: 提醒：gcc是开源的。

user: user-0
content: 问了gcc的工程师，他的回复是：  aarch64固定了 struct/union/array的地址对齐到8字节，为了性能的优化。任何属性的设置都被忽略了。  他建议我在这种use case下避免使用struct。  如果这个编译器特性确实影响很大，可以向aarch64开发方报bug。

user: user-3
content: 引用 69 楼 leslielg 的回复:[quote=引用 67 楼 DelphiGuy 的回复:] [quote=引用 54 楼 leslielg 的回复:] [quote=引用 46 楼 DelphiGuy 的回复:] [quote=引用 44 楼 leslielg 的回复:] [quote=引用 43 楼 DelphiGuy 的回复:] leslielg，瞧你这傻缺紧张的，连续引用两次。 要说逻辑错误么，某个傻缺说的“int在任何编译器都是32位 ”就是典型，逻辑智力不够啊。 至于你的所谓“问题”，我已经明确告诉你了，变量首地址对齐要用__attribute__((aligned(n))); 这是gcc文档中明确写了的，也是经过实践检验的，你的“问题”很可能是人品问题。  你这弱智跑来说一堆都是前面回帖里重复过的话，你看不懂前面写的字？__attribute__ aligned在之前就说过了，你跑来重提一遍还以为就是要害，你要么瞎要么智力不足。 int在任何编译器都是32位这个问题，我也明确回复过你让你说一个int不是32位的编译器出来，你又说不出来。你凭想象发言？  谈技术就谈技术，技术说不清了就扯出人品道德之类，你当什么程序员。劝你赶紧转行。[/quote]  你这傻缺果然是逻辑智力不够啊，且不说以前大把的dos、win16编译器int是16位的，就说现在，intel C++、Fortran也支持ilp64和lp64两种模型，ilp64模型的int就是64位的，见：https://software.intel.com/en-us/node/528863 多学着点吧，傻缺。 [/quote]  以前还有8位的编译器，任天堂的游戏机用的它，但是这种曾经存在过的编译器跟_现在的编译器_什么关联？拿过去的编译器来讨论现在的标准？你是哪里有毛病？  C语言的int长度是C的标准，跟Fortran什么关联？？？？？  说你傻缺不冤枉，找不到任何逻辑。[/quote]  傻缺你又跳出来表演你的智商。 1. intel C++、Fortran就是现在的编译器，你这狗脑子看不懂人话。 2. 你这狗脑子忘记你自己说的是“我也明确回复过你让你说一个int不是32位的编译器出来”，就在你的引用中不还有么。 3. 那么大的intel C++没看见么。 你继续跳好了，就让你继续表演，让大家好好欣赏你的嘴脸。 [/quote]  你这么傻逼，还如此三番五次的来秀你那进水的脑。难道是读不懂骂你的点？换个有点羞耻心的人早回炉重造去了。 [/quote]   继续回，回一次我就曹尼玛一次。尼玛不爽的话，就用辣椒曹尼玛，曹到尼玛叫到死为止。

user: user-4
content: 引用 69 楼 leslielg 的回复:[quote=引用 67 楼 DelphiGuy 的回复:] [quote=引用 54 楼 leslielg 的回复:] [quote=引用 46 楼 DelphiGuy 的回复:] [quote=引用 44 楼 leslielg 的回复:] [quote=引用 43 楼 DelphiGuy 的回复:] leslielg，瞧你这傻缺紧张的，连续引用两次。 要说逻辑错误么，某个傻缺说的“int在任何编译器都是32位 ”就是典型，逻辑智力不够啊。 至于你的所谓“问题”，我已经明确告诉你了，变量首地址对齐要用__attribute__((aligned(n))); 这是gcc文档中明确写了的，也是经过实践检验的，你的“问题”很可能是人品问题。  你这弱智跑来说一堆都是前面回帖里重复过的话，你看不懂前面写的字？__attribute__ aligned在之前就说过了，你跑来重提一遍还以为就是要害，你要么瞎要么智力不足。 int在任何编译器都是32位这个问题，我也明确回复过你让你说一个int不是32位的编译器出来，你又说不出来。你凭想象发言？  谈技术就谈技术，技术说不清了就扯出人品道德之类，你当什么程序员。劝你赶紧转行。[/quote]  你这傻缺果然是逻辑智力不够啊，且不说以前大把的dos、win16编译器int是16位的，就说现在，intel C++、Fortran也支持ilp64和lp64两种模型，ilp64模型的int就是64位的，见：https://software.intel.com/en-us/node/528863 多学着点吧，傻缺。 [/quote]  以前还有8位的编译器，任天堂的游戏机用的它，但是这种曾经存在过的编译器跟_现在的编译器_什么关联？拿过去的编译器来讨论现在的标准？你是哪里有毛病？  C语言的int长度是C的标准，跟Fortran什么关联？？？？？  说你傻缺不冤枉，找不到任何逻辑。[/quote]  傻缺你又跳出来表演你的智商。 1. intel C++、Fortran就是现在的编译器，你这狗脑子看不懂人话。 2. 你这狗脑子忘记你自己说的是“我也明确回复过你让你说一个int不是32位的编译器出来”，就在你的引用中不还有么。 3. 那么大的intel C++没看见么。 你继续跳好了，就让你继续表演，让大家好好欣赏你的嘴脸。 [/quote]  你这么傻逼，还如此三番五次的来秀你那进水的脑。难道是读不懂骂你的点？换个有点羞耻心的人早回炉重造去了。 [/quote]  "换个有点羞耻心的人早回炉重造去了" 这话说得太好了，你咋这么有自知之明呢，你的那些笑料在这贴子里一直存在，你能让它们消失么？你是不是以为自己继续嘴硬就没有闹笑话？认清现实吧，傻缺。

user: user-0
content: 引用 67 楼 DelphiGuy 的回复:[quote=引用 54 楼 leslielg 的回复:] [quote=引用 46 楼 DelphiGuy 的回复:] [quote=引用 44 楼 leslielg 的回复:] [quote=引用 43 楼 DelphiGuy 的回复:] leslielg，瞧你这傻缺紧张的，连续引用两次。 要说逻辑错误么，某个傻缺说的“int在任何编译器都是32位 ”就是典型，逻辑智力不够啊。 至于你的所谓“问题”，我已经明确告诉你了，变量首地址对齐要用__attribute__((aligned(n))); 这是gcc文档中明确写了的，也是经过实践检验的，你的“问题”很可能是人品问题。  你这弱智跑来说一堆都是前面回帖里重复过的话，你看不懂前面写的字？__attribute__ aligned在之前就说过了，你跑来重提一遍还以为就是要害，你要么瞎要么智力不足。 int在任何编译器都是32位这个问题，我也明确回复过你让你说一个int不是32位的编译器出来，你又说不出来。你凭想象发言？  谈技术就谈技术，技术说不清了就扯出人品道德之类，你当什么程序员。劝你赶紧转行。[/quote]  你这傻缺果然是逻辑智力不够啊，且不说以前大把的dos、win16编译器int是16位的，就说现在，intel C++、Fortran也支持ilp64和lp64两种模型，ilp64模型的int就是64位的，见：https://software.intel.com/en-us/node/528863 多学着点吧，傻缺。 [/quote]  以前还有8位的编译器，任天堂的游戏机用的它，但是这种曾经存在过的编译器跟_现在的编译器_什么关联？拿过去的编译器来讨论现在的标准？你是哪里有毛病？  C语言的int长度是C的标准，跟Fortran什么关联？？？？？  说你傻缺不冤枉，找不到任何逻辑。[/quote]  傻缺你又跳出来表演你的智商。 1. intel C++、Fortran就是现在的编译器，你这狗脑子看不懂人话。 2. 你这狗脑子忘记你自己说的是“我也明确回复过你让你说一个int不是32位的编译器出来”，就在你的引用中不还有么。 3. 那么大的intel C++没看见么。 你继续跳好了，就让你继续表演，让大家好好欣赏你的嘴脸。 [/quote]  你这么傻逼，还如此三番五次的来秀你那进水的脑。难道是读不懂骂你的点？换个有点羞耻心的人早回炉重造去了。

user: user-4
content: 引用 54 楼 leslielg 的回复:[quote=引用 46 楼 DelphiGuy 的回复:] [quote=引用 44 楼 leslielg 的回复:] [quote=引用 43 楼 DelphiGuy 的回复:] leslielg，瞧你这傻缺紧张的，连续引用两次。 要说逻辑错误么，某个傻缺说的“int在任何编译器都是32位 ”就是典型，逻辑智力不够啊。 至于你的所谓“问题”，我已经明确告诉你了，变量首地址对齐要用__attribute__((aligned(n))); 这是gcc文档中明确写了的，也是经过实践检验的，你的“问题”很可能是人品问题。  你这弱智跑来说一堆都是前面回帖里重复过的话，你看不懂前面写的字？__attribute__ aligned在之前就说过了，你跑来重提一遍还以为就是要害，你要么瞎要么智力不足。 int在任何编译器都是32位这个问题，我也明确回复过你让你说一个int不是32位的编译器出来，你又说不出来。你凭想象发言？  谈技术就谈技术，技术说不清了就扯出人品道德之类，你当什么程序员。劝你赶紧转行。[/quote]  你这傻缺果然是逻辑智力不够啊，且不说以前大把的dos、win16编译器int是16位的，就说现在，intel C++、Fortran也支持ilp64和lp64两种模型，ilp64模型的int就是64位的，见：https://software.intel.com/en-us/node/528863 多学着点吧，傻缺。 [/quote]  以前还有8位的编译器，任天堂的游戏机用的它，但是这种曾经存在过的编译器跟_现在的编译器_什么关联？拿过去的编译器来讨论现在的标准？你是哪里有毛病？  C语言的int长度是C的标准，跟Fortran什么关联？？？？？  说你傻缺不冤枉，找不到任何逻辑。[/quote]  傻缺你又跳出来表演你的智商。 1. intel C++、Fortran就是现在的编译器，你这狗脑子看不懂人话。 2. 你这狗脑子忘记你自己说的是“我也明确回复过你让你说一个int不是32位的编译器出来”，就在你的引用中不还有么。 3. 那么大的intel C++没看见么。 你继续跳好了，就让你继续表演，让大家好好欣赏你的嘴脸。

user: user-0
content: 引用 65 楼 zhao4zhong1 的回复:提醒：gcc是开源的。  这里讨论了这个问题。据他们工程师说在6月份release的版本里修复了这个问题。使用-Os可以取消 8字节对齐这个限制。  https://gcc.gnu.org/ml/gcc-patches/2017-05/msg00073.html  但是我还是希望用attribute来设置对齐，比较灵活，不想用-Os。 好在问题明确了。

user: user-2
content: 引用 27 楼 leslielg 的回复:[quote=引用 21 楼 zhao4zhong1 的回复:] 不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！  http://edu.csdn.net/course/detail/2344 C语言指针与汇编内存地址-一.代码要素  能直接说明你的观点和建议么？[/quote] 学会使用调试窗口、内存窗口查看内存对齐的实际情况。 http://edu.csdn.net/course/detail/2344 C语言指针与汇编内存地址-一.代码要素

user: user-0
content: 引用 21 楼 zhao4zhong1 的回复:不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！  http://edu.csdn.net/course/detail/2344 C语言指针与汇编内存地址-一.代码要素  能直接说明你的观点和建议么？

user: user-0
content: 引用 24 楼 lonelyhacker 的回复:uint32_t这个本身在gcc中是4字节对齐的。并不是8字节对齐的。  单字节 -> 地址是偶数地址 双字节 -> 地址是被4整除的地址 四字节 -> 地址是被8整除的地址  你这又是在胡说八道了  uint32_t占的长度是4字节，*并不代表它的地址是4字节对齐*，在可以非对齐访问的机器上(比如arm cortex A), uin32_t变量可以放到任何非对齐的地址上访问。  以下3句完全不明白在说什么，单字节必须是偶数地址那奇数地址放的是啥？  单字节 -> 地址是偶数地址 双字节 -> 地址是被4整除的地址 四字节 -> 地址是被8整除的地址

user: user-0
content: 引用 23 楼 lonelyhacker 的回复:int在任何编译器都是32位？？？？？？  这个说法有点屌。。 第一次看到有人这样说的。  现在有int不是32位的编译器？你说个出来看看

user: user-3
content: 引用 59 楼 leslielg 的回复:[quote=引用 51 楼 lonelyhacker 的回复:] [quote=引用 26 楼 leslielg 的回复:] [quote=引用 24 楼 lonelyhacker 的回复:] uint32_t这个本身在gcc中是4字节对齐的。并不是8字节对齐的。  单字节 -> 地址是偶数地址 双字节 -> 地址是被4整除的地址 四字节 -> 地址是被8整除的地址  你这又是在胡说八道了  uint32_t占的长度是4字节，*并不代表它的地址是4字节对齐*，在可以非对齐访问的机器上(比如arm cortex A), uin32_t变量可以放到任何非对齐的地址上访问。  以下3句完全不明白在说什么，单字节必须是偶数地址那奇数地址放的是啥？  单字节 -> 地址是偶数地址 双字节 -> 地址是被4整除的地址 四字节 -> 地址是被8整除的地址[/quote]   你现在讨论的是非对齐的吗？你现在所说的是arm cortex A吗？起始地址是偶数，奇数拿来干嘛？你猜拿来干嘛。 你的智力不适合当程序员。其他工作也不适合你，因为你装逼，而且装得很失败。 [/quote]  傻逼你概念都是错的。后面还讨论什么。还什么起始地址必须是偶数，一个地址就表示一个单字节。偶数奇数都是一个字节地址。 uint32_t这是个变量类型，跟对齐毫无关系。而且aarch64编译器就是给arm cortex A用的。  你要抬扛，要指出技术上的硬伤，是你能站住脚的基础。你说出错这么远的概念，还来跟我扯，不骂你傻逼对不起程序员这3个字。  你个傻逼还是算了吧，教不了你。[/quote]   怪不得这么多人在骂你傻逼。说了技术和智商都是你的硬伤。别做了。听爹的。该死那就死哪里去吧。

user: user-0
content: 引用 51 楼 lonelyhacker 的回复:[quote=引用 26 楼 leslielg 的回复:] [quote=引用 24 楼 lonelyhacker 的回复:] uint32_t这个本身在gcc中是4字节对齐的。并不是8字节对齐的。  单字节 -> 地址是偶数地址 双字节 -> 地址是被4整除的地址 四字节 -> 地址是被8整除的地址  你这又是在胡说八道了  uint32_t占的长度是4字节，*并不代表它的地址是4字节对齐*，在可以非对齐访问的机器上(比如arm cortex A), uin32_t变量可以放到任何非对齐的地址上访问。  以下3句完全不明白在说什么，单字节必须是偶数地址那奇数地址放的是啥？  单字节 -> 地址是偶数地址 双字节 -> 地址是被4整除的地址 四字节 -> 地址是被8整除的地址[/quote]   你现在讨论的是非对齐的吗？你现在所说的是arm cortex A吗？起始地址是偶数，奇数拿来干嘛？你猜拿来干嘛。 你的智力不适合当程序员。其他工作也不适合你，因为你装逼，而且装得很失败。 [/quote]  傻逼你概念都是错的。后面还讨论什么。还什么起始地址必须是偶数，一个地址就表示一个单字节。偶数奇数都是一个字节地址。 uint32_t这是个变量类型，跟对齐毫无关系。而且aarch64编译器就是给arm cortex A用的。  你要抬扛，要指出技术上的硬伤，是你能站住脚的基础。你说出错这么远的概念，还来跟我扯，不骂你傻逼对不起程序员这3个字。  你个傻逼还是算了吧，教不了你。

user: user-0
content: 引用 56 楼 lonelyhacker 的回复:楼主傻比。。。你上面说的是  有int不是32位的编译器。。。现在加了个“现在”两个字，你现在不用，表示别人没用吗？智障玩意。  智力正常的都不会非要去把8位时代的编译器扯出来，跟现在的讨论毫无关联。这种计算机发展史的讨论你跟你认识的傻逼们说去。

user: user-3
content: 楼主傻比。。。你上面说的是  有int不是32位的编译器。。。现在加了个“现在”两个字，你现在不用，表示别人没用吗？智障玩意。

user: user-0
content: 引用 46 楼 DelphiGuy 的回复:[quote=引用 44 楼 leslielg 的回复:] [quote=引用 43 楼 DelphiGuy 的回复:] leslielg，瞧你这傻缺紧张的，连续引用两次。 要说逻辑错误么，某个傻缺说的“int在任何编译器都是32位 ”就是典型，逻辑智力不够啊。 至于你的所谓“问题”，我已经明确告诉你了，变量首地址对齐要用__attribute__((aligned(n))); 这是gcc文档中明确写了的，也是经过实践检验的，你的“问题”很可能是人品问题。  你这弱智跑来说一堆都是前面回帖里重复过的话，你看不懂前面写的字？__attribute__ aligned在之前就说过了，你跑来重提一遍还以为就是要害，你要么瞎要么智力不足。 int在任何编译器都是32位这个问题，我也明确回复过你让你说一个int不是32位的编译器出来，你又说不出来。你凭想象发言？  谈技术就谈技术，技术说不清了就扯出人品道德之类，你当什么程序员。劝你赶紧转行。[/quote]  你这傻缺果然是逻辑智力不够啊，且不说以前大把的dos、win16编译器int是16位的，就说现在，intel C++、Fortran也支持ilp64和lp64两种模型，ilp64模型的int就是64位的，见：https://software.intel.com/en-us/node/528863 多学着点吧，傻缺。 [/quote]  以前还有8位的编译器，任天堂的游戏机用的它，但是这种曾经存在过的编译器跟_现在的编译器_什么关联？拿过去的编译器来讨论现在的标准？你是哪里有毛病？  C语言的int长度是C的标准，跟Fortran什么关联？？？？？  说你傻缺不冤枉，找不到任何逻辑。

user: user-3
content: 引用 26 楼 leslielg 的回复:[quote=引用 24 楼 lonelyhacker 的回复:] uint32_t这个本身在gcc中是4字节对齐的。并不是8字节对齐的。  单字节 -> 地址是偶数地址 双字节 -> 地址是被4整除的地址 四字节 -> 地址是被8整除的地址  你这又是在胡说八道了  uint32_t占的长度是4字节，*并不代表它的地址是4字节对齐*，在可以非对齐访问的机器上(比如arm cortex A), uin32_t变量可以放到任何非对齐的地址上访问。  以下3句完全不明白在说什么，单字节必须是偶数地址那奇数地址放的是啥？  单字节 -> 地址是偶数地址 双字节 -> 地址是被4整除的地址 四字节 -> 地址是被8整除的地址[/quote]   你现在讨论的是非对齐的吗？你现在所说的是arm cortex A吗？起始地址是偶数，奇数拿来干嘛？你猜拿来干嘛。 你的智力不适合当程序员。其他工作也不适合你，因为你装逼，而且装得很失败。

user: user-0
content: 引用 48 楼 DelphiGuy 的回复:[quote=引用 45 楼 leslielg 的回复:] [quote=引用 43 楼 DelphiGuy 的回复:] leslielg，瞧你这傻缺紧张的，连续引用两次。 要说逻辑错误么，某个傻缺说的“int在任何编译器都是32位 ”就是典型，逻辑智力不够啊。 至于你的所谓“问题”，我已经明确告诉你了，变量首地址对齐要用__attribute__((aligned(n))); 这是gcc文档中明确写了的，也是经过实践检验的，你的“问题”很可能是人品问题。  而且 __attribute__((aligned(n)))要怎么用你知道么？你还看了文档，一知半解就跑来发言，我写__attribute__((packed)))的地方能替换成aligned？还实践检验。 你写的这些东西基本上都是错的，引人耻笑。[/quote]  你这傻缺果然是一脑子浆糊，看看你在#15说了些啥？  引用 15 楼 leslielg 的回复:[quote=引用 11 楼 bravery36 的回复:] 另外，还可以用 __attribute__((packed))来取消填充。  你说的这个是结构体的内部对齐和填充，我问的是结构体被编译到的首地址。  另外你觉得我写这个结构体会产生8字节对齐？唯一一个成员就是4字节[/quote]  别人告诉你__attribute__((packed))，你说“这个是结构体的内部对齐和填充，我问的是结构体被编译到的首地址”，结果你代码你还用__attribute__((packed))，我告诉你了变量首地址对齐要用__attribute__((aligned(n)));  你又跑出来说“我写__attribute__((packed)))的地方能替换成aligned”，你说说你是不是傻缺、人品有问题？ [/quote]  这里的这个packed是用来pack结构体内部的对齐的，这个结构体本来内容不止这一个变量，所以需要pack，我删除了其它内容方便说明问题。你非要以为是用来对齐首地址的，而且还是在我前面说过了pack是用来内部对齐的情况下，不说你弱智说你啥？  而且要写aligned也不是在这个位置，这个位置跟aligned 毫无关系，是你看不懂非要把这个packed扯进来。说你半天都想不明白，你个傻缺。

user: user-4
content: 引用 45 楼 leslielg 的回复:[quote=引用 43 楼 DelphiGuy 的回复:] leslielg，瞧你这傻缺紧张的，连续引用两次。 要说逻辑错误么，某个傻缺说的“int在任何编译器都是32位 ”就是典型，逻辑智力不够啊。 至于你的所谓“问题”，我已经明确告诉你了，变量首地址对齐要用__attribute__((aligned(n))); 这是gcc文档中明确写了的，也是经过实践检验的，你的“问题”很可能是人品问题。  而且 __attribute__((aligned(n)))要怎么用你知道么？你还看了文档，一知半解就跑来发言，我写__attribute__((packed)))的地方能替换成aligned？还实践检验。 你写的这些东西基本上都是错的，引人耻笑。[/quote]  你这傻缺果然是一脑子浆糊，看看你在#15说了些啥？  引用 15 楼 leslielg 的回复:[quote=引用 11 楼 bravery36 的回复:] 另外，还可以用 __attribute__((packed))来取消填充。  你说的这个是结构体的内部对齐和填充，我问的是结构体被编译到的首地址。  另外你觉得我写这个结构体会产生8字节对齐？唯一一个成员就是4字节[/quote]  别人告诉你__attribute__((packed))，你说“这个是结构体的内部对齐和填充，我问的是结构体被编译到的首地址”，结果你代码你还用__attribute__((packed))，我告诉你了变量首地址对齐要用__attribute__((aligned(n)));  你又跑出来说“我写__attribute__((packed)))的地方能替换成aligned”，你说说你是不是傻缺、人品有问题？