a
нельзя сохранить в регистре, так как вы взяли его адрес. (Вальдо правильно указывает, что действительно умный компилятор может оптимизировать доступ к массиву в битовые операции и оставить a
в регистре, но я никогда не видел, чтобы компилятор делал это, и я не уверен это было бы быстрее).
arr
(сам указатель) сохраняется в регистре (%edi
, на amd64). Содержимое массива находится в памяти.
- Приведение типа указателя само по себе часто вообще не генерирует код. Однако глупые поступки с приведением типов могут привести к очень неэффективному коду или даже к коду, поведение которого не определено.
Похоже, вы пытаетесь переставить байты в массиве, а затем засунуть их в число, и машинный код, который генерирует ваш пример, не так уж плох для этого. Предложение Дэвида использовать вместо этого операции сдвига и маски хорошо (это также позволит избежать проблем, если ваш код когда-либо должен будет выполняться на машине с прямым порядком байтов), а также есть инструкции SSE векторного перестановки, но я слышал, что они вроде боли использовать.
Между прочим, вы должны установить тип возвращаемого значения для вашей примерной функции unsigned long
и поставить return a;
в самом конце; тогда вы можете использовать gcc -O2 -S
и посмотреть точно, что вы получите от компиляции. Без изменения, возвращающего a
, GCC с радостью оптимизирует весь корпус функции, поскольку не имеет никаких видимых извне побочных эффектов.