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

ARM32 GCC环境下unsigned long long栈传参8字节对齐异常排查

问题原因分析

1. 未遵循Cortex-R52的AAPCS调用约定

你使用的gcc-arm-none-eabi-9-2020-q2-update针对Cortex-R52(ARMv8-R架构)遵循AAPCS64/ARMv8-R调用约定,对于可变参数函数的64位整数参数(如unsigned long long):

  • 当启用硬浮点ABI(-mfloat-abi=hard)时,前几个64位参数会优先使用通用寄存器对(如R0+R1)传递,而非直接压栈。
  • 若_printf中对va_list的处理(如va_start/va_arg)未适配AAPCS规则,会错误跳过寄存器中的参数,直接去栈上查找,导致va_list指向的地址不包含目标参数。
  • 另外,若_printf的函数声明未正确使用可变参数语法(如_printf(const char* fmt, ...)),GCC会按普通函数调用约定处理参数,进一步加剧传参位置混乱。

2. 小端字节序处理错误

Cortex-R52默认采用小端字节序,unsigned long long类型的0x123456789abcdef0在内存中存储顺序为:0xf0 0xde 0xbc 0x9a 0x78 0x56 0x34 0x12(低字节在前)。

  • 你的my_vprintf处理%lx格式符时,错误颠倒了高32位与低32位的读取顺序:正确逻辑应先读低32位0x9abcdef0、再读高32位0x12345678,但代码实际先读取高地址的0x12345678、再读低地址的0x9abcdef0,最终拼接成错误的0x9abcdef012345678。

3. 独立执行环境的标准库适配问题

编译参数使用了-nostartfiles -ffreestanding,意味着处于无操作系统的独立执行环境,GCC提供的标准va_list宏(如va_start/va_arg)可能未被正确初始化,或者你手动实现的可变参数处理逻辑未适配ARMv8-R的架构细节,导致无法正确解析寄存器和栈上的参数位置。

内容的提问来源于stack exchange,提问作者shifeng.yuan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 18:56:15