ARM Assembly - Преобразование порядка байтов - PullRequest
2 голосов
/ 03 мая 2010

В настоящее время это домашнее задание, над которым я и мой товарищ по команде застряли. Мы не получили большого представления о Ассамблее, и это должно быть нашим первым домашним заданием. Задача состоит в том, чтобы создать программу, которая преобразует 0xAABBCCDD в 0xDDCCBBAA.

Я не ищу ответа, так как это победит цель, но мы сильно разочарованы трудностью этой глупости. Мы думаем, что у нас хорошее начало в создании жизнеспособного решения, но мы просто не можем придумать остальную часть программы.

Во-первых, мы маскируем каждый отдельный пучок (aa), (bb), (cc), (dd) в другой регистр:

LDR R0, LittleEndian    // 0xAABBCCDD
AND R1, R0, #0xFF000000 // 0xAA
AND R2, R0, #0x00FF0000 // 0xBB
AND R3, R0, #0x0000FF00 // 0xCC
AND R4, R0, #0x000000FF // 0xDD

Затем мы пытаемся перестроить их в регистр R0, но, черт возьми, если бы мы могли найти хорошее решение ...

Наше лучшее усилие пришло от:

ORR R0, R1, LSL #24 
ORR R0, R2, LSL #8
ORR R0, R3, LSR #8
ORR R0, R4, LSR #24

, который произвел 0xBBBBCCDD по какой-то странной причине; мы действительно не знаем.

Любые советы будут с благодарностью. Опять же, мы просим о помощи, но не о решении.

Ура!

Ответы [ 5 ]

5 голосов
/ 03 мая 2010

На ARMv6 и выше вы можете просто использовать инструкцию rev, но я предполагаю, что вам не разрешено делать это по любой причине.

Что касается того, почему вы получили результат, который я получил, я просмотрел ваш код и прокомментировал фактические значения регистров, с которыми оперировали:

LDR R0, LittleEndian    // r0 = 0xAABBCCDD
AND R1, R0, #0xFF000000 // r1 = 0xAA000000
AND R2, R0, #0x00FF0000 // r2 = 0x00BB0000
AND R3, R0, #0x0000FF00 // r3 = 0x0000CC00
AND R4, R0, #0x000000FF // r4 = 0x000000DD

ORR R0, R1, LSL #24     // r0 = 0xAABBCCDD | 0x00000000 = 0xAABBCCDD
ORR R0, R2, LSL #8      // r0 = 0xAABBCCDD | 0xBB000000 = 0xBBBBCCDD
ORR R0, R3, LSR #8      // r0 = 0xBBBBCCDD | 0x000000CC = 0xBBBBCCDD
ORR R0, R4, LSR #24     // r0 = 0xBBBBCCDD | 0x00000000 = 0xBBBBCCDD

То, что происходит здесь, это то, что у вас есть направления сдвига назад; вместо смещения влево 0xAA000000 на 24, вы хотите вправо сместить его на 24, давая 0x000000AA. Более того, вы никогда не обнуляете содержимое r0, что вам также необходимо сделать, чтобы этот подход работал. Если вы исправите эти проблемы, ваш код будет работать так, как задумано (хотя есть и более компактные способы решения той же задачи).

3 голосов
/ 03 мая 2010

Я думаю, вам нужно сделать (ARM немного ржавый):

MOV R0, R1, LSR #24 
ORR R0, R2, LSR #8
ORR R0, R3, LSL #8
ORR R0, R4, LSL #24

То есть MOV в первой инструкции, поскольку вы не хотите, чтобы что-либо из старого R0 влияло на новое значение.

Я не вижу способа сделать эту подсказку более похожей, поскольку вы все равно эффективно проделали всю работу.

3 голосов
/ 03 мая 2010

Ваш код выглядит хорошо.

Ваша ошибка в том, что вы изменили значение LSL и LSR.

Возьмите R0 например:

AND R1, R0, #0xFF000000 // 0xAA

Результат этой операции не генерирует 0xAA. Генерирует 0xAA000000.

Вторая инструкция, которая обрабатывает R1:

ORR R0, R1, LSL #24 

Сместит данные из регистра. От верхних 8 бит просто не осталось места.

Если otoh, вы сдвигаете данные вправо так:

ORR R0, R1, LSR #24 

Данные заканчиваются младшим байтом. Где вы хотите, чтобы это было. Это должно помочь вам сделать домашнее задание. : -)

2 голосов
/ 17 апреля 2012

Хотя вопрос довольно старый, я хотел добавить свое предложение для кода, потому что ему просто нужно 6 инструкций вместо 8. Ему также нужно только 3 регистра вместо 5. Это должно быть лучшим решением для всего, что было до armv6 (с инструкцией rev).

// We're starting with r0 = 4321
mov r2, r0, lsr #24             // r2 = 0004
and r1, r0, #16711680           // r1 = 0300
orr r2, r2, r0, lsl #24         // r2 = 1004
orr r2, r2, r1, lsr #8          // r2 = 1034
and r0, r0, #65280              // r0 = 0020
orr r0, r2, r0, lsl #8          // r0 = 1234
1 голос
/ 03 мая 2010

Кроме того, похоже, что вы, возможно, не очистили регистр R0 (установите все нулевые биты) перед использованием ORR для перемещения битов назад.

...