У меня есть следующий фрагмент кода:va_arg на ARM Cortex-M4, uint64_t и GCC 4.9
__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
арг2 = 0x24242424F0F0F0F0
arg3 = 0x010048E7
Переменная arg3 см ms, чтобы содержать адрес во Flash.
Я где-то читал, что это может быть связано с выравниванием стека (вот почему вы видите все эти атрибуты выравнивания и, особенно, почему я внедрил мои переменные за пределы области действия). Я также убедился, что мой код скомпилирован с использованием флагов «-mabi = aapcs -std = c99».
Я просмотрел регистры {r0-r3}, когда функция вызывается, и они, как представляется, правильно содержат первые 3 аргумента правильно (r2 и r3, содержащие 64-битное значение в словах с маленькой последовательностью).
Я заметил, что во время исключения (Hard Fault для примера) вариатор функционирует должным образом. И поскольку MCU настроен на использование 8-битного стека при вводе процедуры исключения, имеет смысл это объяснение того, что происходит.
Любая помощь в понимании того, что происходит на самом деле, будет действительно оценена? Как это можно исправить?