в memcpy использовались указатели на long, компилятор считает что они всегда выравнены на границу 4 байт и заюзал команды LDRD STRD которые не умеют обращаться по невыровненному адресу. указатель был невыровненный, что и привело к hardfault. Причем если сделать memcpy((unsigned char*)to, (unsigned char*)from, 8); нихрена не изменится(оптимизация максимальная). Необходимо чтобы указатели были объявлены как указатели на сhar, тогда keil юзает ldr str.