РЕДАКТИРОВАТЬ: я полностью осознаю, что функция asmCopy может быть не функциональной, мой вопрос больше о поведении gcc при передаче параметров в регистрах.
Я работаю над STM32H7 с использованием STM32CubeIDE, чей конструкторarm-none-eabi-gcc
Уровень оптимизации равен -Os
Я вижу следующее поведение, которое не могу объяснить.Я сделал снимок экрана, чтобы получить параллельно asm и C-код.
Мой C-код вызывает 3 функции.Первый и третий имеют абсолютно одинаковые параметры.
Второй параметр не принимает.вот его код:
static void Reset_Cycle_Counter(void)
{
volatile unsigned long *DWT_CYCCNT = (unsigned long *)0xE0001004;
volatile unsigned long *DWT_CONTROL = (uint32_t *)0xE0001000;
// Reset cycle counter
*DWT_CONTROL = *DWT_CONTROL & ~0x00000001 ;
*DWT_CYCCNT = 0;
*DWT_CONTROL = *DWT_CONTROL | 1 ;
}
Третья функция особенная: я пытаюсь написать некоторый ассемблерный код (который вполне может быть неправильным прямо сейчас).
static void __attribute__((noinline)) asmCopy(void *dst, void *src, uint32_t bytes)
{
while (bytes--)
{
asm("ldrb r12,[r1], #1"); // src param is stored in r1, r12 can be modified without being restored after
asm("strb r12,[r0], #1"); // dst paramis stored in r0
}
}
ПередПри первом вызове функции (в memcpy) r0, r1 и r2 загружаются с правильными значениями.
Затем перед вызовом третьей функции, какниже вы можете видеть, что параметры в r1 и r2 неверны (qspi_addr должен быть 0x90000000).
Я понимаю, что AAPCS (стандарт вызова процедур в ARM) заключается в том, что перед вызовом подпрограммы регистры с r0 по r3 должны быть загружены с параметрами функций (если таковые имеются).).И подпрограмма не должна сохранять или восстанавливать эти регистры.Тогда нормально, что вторая функция изменяет r1 и r2.Поэтому я ожидаю, что компилятор обновит r0, r1 и r2 перед третьим вызовом.
Если я изменю код оптимизации на -O0, я действительно получу это ожидаемое поведение.
Что выдумаете?