You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AArch64内核中值传递15字节结构体时串口输出异常问题

AArch64内核中值传递15字节结构体时串口输出异常问题

我现在在开发一个简单的AArch64内核,遇到了个挺奇怪的问题:当我按值传递一个15字节的结构体时,串口输出的内容和预期的0a1完全对不上;但只要把这个结构体的大小改成16字节,之前的异常就消失了,输出也正常了。

我的开发环境

  • QEMU模拟器版本:9.0.2
  • 编译器版本:aarch64-linux-gnu-g++ (Ubuntu 14.2.0-4ubuntu2) 14.2.0

相关代码片段(main.cpp)

extern "C" void _start() {
    asm volatile("ldr x11, =stack_top\n\t"
    // 剩余代码未完整给出

问题分析与排查建议

这个问题大概率和AArch64的**过程调用标准(PCS)**脱不了干系,我给你捋捋关键逻辑:

在AArch64的官方调用约定里,结构体按值传递时的处理规则是根据大小和对齐属性来定的:

  • 要是结构体总大小≤8字节,直接用单个通用寄存器传递就行;
  • 大小在9-16字节之间的话,会用两个通用寄存器拼接起来传递;
  • 但这里最坑的点是对齐要求——15字节的结构体虽然没到16字节,但AArch64的调用约定可能会要求按16字节的对齐规格来处理传递,要是你的内核代码(比如串口输出函数)没考虑到这种“不完整寄存器传递”的情况,比如默认按16字节来读取参数,那第二个寄存器里的高1字节就是垃圾数据,自然会导致输出异常;而改成16字节后,刚好填满两个寄存器,传递逻辑和内存布局都符合预期,输出就正常了。

另外还有个可能的点:你手写的_start汇编里的栈设置有没有符合AArch64的对齐要求?AArch64明确规定,进入C函数前栈指针必须是16字节对齐的,要是栈没对齐,参数传递时的内存访问很容易出问题,进而影响串口输出的内容。

给你几个排查方向:

  1. 先检查串口输出函数处理这个结构体参数的逻辑——是不是默认按16字节来读取数据,没考虑到15字节的截断情况?
  2. 用-S参数编译代码,看看15字节和16字节结构体在传递时的汇编差异,比如寄存器的使用、栈上临时存储的情况,对比一下就能发现问题;
  3. 确认_start里的栈设置有没有保证16字节对齐,比如stack_top的地址是不是16的倍数;
  4. 给15字节的结构体加个对齐属性__attribute__((aligned(16))),看看加上后输出是否正常——如果正常了,那基本就是对齐导致的传递逻辑差异。

备注:内容来源于stack exchange,提问作者Zone233

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.13 16:58:03