Перестановка байтов в 32 разрядном слове, архитектура MIPS32

Тема в разделе "WASM.ASSEMBLER", создана пользователем savigm, 15 окт 2009.

  1. savigm

    savigm New Member

    Публикаций:
    0
    Регистрация:
    15 окт 2009
    Сообщения:
    4
    Нужно переставить байты местами с Big-Endian на Little-Endian, т.е. 4->1, 3->2, 2->3, 1->4.

    Я это сделал с использованием двух регистров, помимо исходного(архитектура MIPS32):
    Код (Text):
    1.         andi    v0, a0, 0xff
    2.         sll     v0, v1, 8
    3.         srl     a0, a0, 8
    4.         andi    v1, a0, 0xff
    5.         or      v0, v0, v1
    6.         sll     v0, v0, 8
    7.         srl     a0, a0, 8
    8.         andi    v1, a0, 0xff
    9.         or      v0, v0, v1
    10.         sll     v0, v0, 8
    11.         srl     a0, a0, 8
    12.         andi    v1, a0, 0xff
    13.         or      v0, v0, v1
    Исходный регистр a0, результат в v0.

    Вопрос: можно ли сделать то-же самое с использованием одного регистра, помимо исходного, или вообще без использования доп регистров?
    В x86 есть для этих целей специальная инструкция bswap, которая видимо не использует доп. регистров вообще, в MIPS32 подобной инструкции увы нет.
     
  2. bendme

    bendme New Member

    Публикаций:
    0
    Регистрация:
    10 мар 2009
    Сообщения:
    179
    Если я не туплю, то можно с помощью команды логического сдвига сделать.
    Не помню, как называется, помойму rol.
    mov cx,24
    rol eax
     
  3. bendme

    bendme New Member

    Публикаций:
    0
    Регистрация:
    10 мар 2009
    Сообщения:
    179
    нет, туплю
     
  4. savigm

    savigm New Member

    Публикаций:
    0
    Регистрация:
    15 окт 2009
    Сообщения:
    4
    Нашел опечатку в коде, вот правильный:
    Код (Text):
    1.         andi    v0, a0, 0xff
    2.         sll     v0, v0, 8
    3.         srl     a0, a0, 8
    4.         andi    v1, a0, 0xff
    5.         or      v0, v0, v1
    6.         sll     v0, v0, 8
    7.         srl     a0, a0, 8
    8.         andi    v1, a0, 0xff
    9.         or      v0, v0, v1
    10.         sll     v0, v0, 8
    11.         srl     a0, a0, 8
    12.         andi    v1, a0, 0xff
    13.         or      v0, v0, v1
     
  5. reversecode

    reversecode Guest

    Публикаций:
    0
    Код (Text):
    1. LEAF(ntohl)                            # a0 = 0x11223344, return 0x44332211
    2. #ifdef __MIPSEB__
    3.         move    v0, a0
    4. #else
    5.         srl     v1, a0, 24              # v1 = 0x00000011
    6.         sll     v0, a0, 24              # v0 = 0x44000000
    7.         or      v0, v0, v1
    8.         and     v1, a0, 0xff00
    9.         sll     v1, v1, 8               # v1 = 0x00330000
    10.         or      v0, v0, v1
    11.         srl     v1, a0, 8
    12.         and     v1, v1, 0xff00          # v1 = 0x00002200
    13.         or      v0, v0, v1
    14. #endif
    15.         j       ra
    16. END(ntohl)
     
  6. savigm

    savigm New Member

    Публикаций:
    0
    Регистрация:
    15 окт 2009
    Сообщения:
    4
    Это ваша реализация или взяли откуда-то?
    Код конечно более компактный - 9 команд вместо моих 13, но видимо без двух дополнительных регистров не обойтись. Здесь так-же как и у меня используются v0-v1 помимо a0.
     
  7. Black_mirror

    Black_mirror Active Member

    Публикаций:
    0
    Регистрация:
    14 окт 2002
    Сообщения:
    1.035
    savigm
    С одним дополнительным регистром можно сделать примерно так:
    Код (Text):
    1. T=A>>8;
    2. T^=A;
    3. T&=0xFF00FF;
    4. A^=T;
    5. T<<=8;
    6. A^=T;
    7. T=A>>16;
    8. A<<=16;
    9. A|=T;
     
  8. EvilsInterrupt

    EvilsInterrupt Постигающий азы дзена

    Публикаций:
    0
    Регистрация:
    28 окт 2003
    Сообщения:
    2.428
    Адрес:
    Russia
  9. ConstZ

    ConstZ New Member

    Публикаций:
    0
    Регистрация:
    18 фев 2008
    Сообщения:
    42
    Для временного пользования изначально существует регистр at (assembler temporary), а во второй (современной) версии MIPS32 появилась комманда wsbh - своеобразный byte swap.
     
  10. savigm

    savigm New Member

    Публикаций:
    0
    Регистрация:
    15 окт 2009
    Сообщения:
    4
    Да, я вчера тоже до этого докопался из исходников ядра linux - /usr/src/linux/include/asm-mips/byteorder.h.
    Есть две команды, которые все делают: wsbh и rotr.
    Код (Text):
    1. lw   t0, 0(a1)  /* Read word value */
    2. wsbh t0, t0     /* Convert endiannes of the halfwords */
    3. rotr t0, t0, 16 /* Swap the halfwords within the words */
    Это лучший вариант, но мне он увы не подходит, т.к. это команды MIPS32 Release 2, а я работаю с Release1, т.е. для меня лучшим вариантом будет тот, что предложил думаю вопрос можно считать решенным.
     
  11. Black_mirror

    Black_mirror Active Member

    Публикаций:
    0
    Регистрация:
    14 окт 2002
    Сообщения:
    1.035
    Код (Text):
    1. ;a0=11223344
    2. srl v0,a0,8
    3. or v0,v0,0xFF00
    4. xor v0,v0,0xFF00;00110033
    5. or a0,a0,0xFF00
    6. xor a0,a0,0xFF00
    7. sll a0,a0,8;22004400
    8. or a0,a0,v0;22114433
    9. srl v0,a0,16
    10. sll a0,a0,16
    11. or v0,v0,a0;44332211
     
  12. ConstZ

    ConstZ New Member

    Публикаций:
    0
    Регистрация:
    18 фев 2008
    Сообщения:
    42
    Откуда вообще взялось такое "странное" требование? Имея в распоряжении десятки регистров, пользоваться одним-двумя (IMHO) неразумно - ложные зависимости будут тормозить конвейер!