Я новичок в сборке ARM, так что держись со мной.Я пишу приложение для визуализации музыки для Android.Я нахожусь в точке, где я хочу работать над оптимизацией, так что сейчас я как бы экспериментирую.Ниже моя попытка 8-битной гибридной реализации memset ASM и C.
Где-то это вызывает сбой.Я не могу подключить GDB к процессу, потому что приложение закрывается до запуска GDB, поэтому я не могу выполнить операции.
Это выглядит правильно?Я никогда не был полностью занят выравниванием памяти, но я знаю, что ARM выровнен на 4 байта.Я не уверен, является ли это подсказкой к решению или нет.Я думаю, что гибридный подход, состоящий в том, чтобы разместить большую часть операций в цикле сборки, а затем завершить его до 8 байт за проход, решает любые проблемы с выравниванием.Правильно ли я думаю об этом?Я озадачен тем, что происходит не так.Это действительно похоже на функцию memcpy, и моей единственной проблемой в то время было то, что список клоббера был пуст.Добавление этих регистров в список clobber завершило работу функции, и я просто не могу понять, чего мне не хватает с этой функцией memset.
Любые подсказки?
* Memset functions, 1 byte memset */
static void *mem_set8_arm (void *dest, int c, visual_size_t n)
{
uint32_t *d = dest;
uint8_t *dc = dest;
uint32_t setflag32 =
(c & 0xff) |
((c << 8) & 0xff00) |
((c << 16) & 0xff0000) |
((c << 24) & 0xff000000);
uint8_t setflag8 = c & 0xff;
#if defined(VISUAL_ARCH_ARM)
while (n >= 64) {
__asm __volatile
(
"\n\t mov r4, %[flag]"
"\n\t mov r5, r4"
"\n\t mov r6, r4"
"\n\t mov r7, r4"
"\n\t stmia %[dst]!,{r4-r7}"
"\n\t stmia %[dst]!,{r4-r7}"
:: [dst] "r" (d), [flag] "r" (&setflag32) : "r4", "r4", "r6", "r7");
d += 16;
n -= 64;
}
#endif /* VISUAL_ARCH_ARM */
while (n >= 4) {
*d++ = setflag32;
n -= 4;
}
dc = (uint8_t *) d;
while (n--)
*dc++ = setflag8;
return dest;
}