次のコードがあります。
__attribute__((aligned(0x1000))) static void doVariadic(const uint32_t fmt, ...);
__attribute__((aligned(0x1000))) va_list ap;
__attribute__((aligned(0x1000))) uint32_t value1 = 0xABABABAB;
__attribute__((aligned(0x1000))) uint64_t value2 = 0xF0F0F0F0E1E1E1E1LLU;
__attribute__((aligned(0x1000))) uint32_t value3 = 0x24242424;
__attribute__((aligned(0x1000))) uint32_t arg1;
__attribute__((aligned(0x1000))) uint64_t arg2;
__attribute__((aligned(0x1000))) uint32_t arg3;
__attribute__((aligned(0x1000))) int main(void)
{
doVariadic(0x0UL, value1, value2, value3);
}
__attribute__((aligned(0x1000))) static void doVariadic(const uint32_t fmt, ...)
{
va_start(ap, fmt);
arg1 = va_arg(ap, uint32_t);
arg2 = va_arg(ap, uint64_t);
arg3 = va_arg(ap, uint32_t);
UNUSED(arg1);
UNUSED(arg2);
UNUSED(arg3);
}
これを実行すると、次の値が得られます。
arg1 = 0xABABABAB
arg2 = 0x24242424F0F0F0F0
arg3 = 0x010048E7
変数 arg3 には Flash のアドレスが含まれているようです。
これはスタック アライメントが原因である可能性があることをどこかで読みました (これが、これらすべてのアライメント属性が表示される理由であり、特に変数を関数スコープ外に外部化した理由です)。また、「-mabi=aapcs -std=c99」フラグを使用してコードがコンパイルされていることも確認しました。
関数が呼び出されたときに {r0-r3} レジスタを調べたところ、最初の 3 つの引数が正しく含まれているようです (r2 と r3 にはリトルエンディアン ワードで 64 ビット値が含まれています)。
例外中 (たとえばハード フォールト)、可変個引数が適切に機能することに気付きました。また、MCU は例外ルーチンに入るときに 8 ビット スタックを使用するように設定されているため、これが何が起こっているかの説明になります。
実際に何が起こっているのかを理解するための助けは本当にありがたいですか? これはどのように修正できますか?