r10 содержит младшие 32 бита, а r11 содержит старшие 32 бита.
r10 r11
0 1 2 3 4 5 6 7
Результат, который вы хотите, выглядит следующим образом:
r12
3 4 5 6
То есть конечный результат будет содержать младшие 24 бита r11 и старшие 8 бит r10. Если вы используете беззнаковую арифметику, извлечь биты так просто. Поскольку вы используете подписанную арифметику, вам нужно сохранить знак. Также обратите внимание, что по необходимости вы также отбрасываете старшие 8 бит, конвертируя long long в целое число.
Сначала давайте переместим младшие 24 бита r11 в их окончательное положение. Арифметическое смещение влево гарантирует сохранение знака.
mov r12, r11 asl #8
Теперь вставьте эти биты в соответствующее место в r12. Мы уже убедились, что знак был верным для старших битов, поэтому здесь просто используйте логический сдвиг.
orr r12, r10 lsr #24
Вышеуказанное эквивалентно этому C:
r12 = ((signed)r11 << 8);
r12 |= ((unsigned)r10 >> 24);
Конечно, вы можете просто позволить компилятору сгенерировать такой код для вас. Чтобы компилятор корректно переместил long long в C, вам нужно использовать:
int res = (acc >> 24LL);