Нужно переставить байты местами с Big-Endian на Little-Endian, т.е. 4->1, 3->2, 2->3, 1->4. Я это сделал с использованием двух регистров, помимо исходного(архитектура MIPS32): Код (Text): andi v0, a0, 0xff sll v0, v1, 8 srl a0, a0, 8 andi v1, a0, 0xff or v0, v0, v1 sll v0, v0, 8 srl a0, a0, 8 andi v1, a0, 0xff or v0, v0, v1 sll v0, v0, 8 srl a0, a0, 8 andi v1, a0, 0xff or v0, v0, v1 Исходный регистр a0, результат в v0. Вопрос: можно ли сделать то-же самое с использованием одного регистра, помимо исходного, или вообще без использования доп регистров? В x86 есть для этих целей специальная инструкция bswap, которая видимо не использует доп. регистров вообще, в MIPS32 подобной инструкции увы нет.
Если я не туплю, то можно с помощью команды логического сдвига сделать. Не помню, как называется, помойму rol. mov cx,24 rol eax
Нашел опечатку в коде, вот правильный: Код (Text): andi v0, a0, 0xff sll v0, v0, 8 srl a0, a0, 8 andi v1, a0, 0xff or v0, v0, v1 sll v0, v0, 8 srl a0, a0, 8 andi v1, a0, 0xff or v0, v0, v1 sll v0, v0, 8 srl a0, a0, 8 andi v1, a0, 0xff or v0, v0, v1
Код (Text): LEAF(ntohl) # a0 = 0x11223344, return 0x44332211 #ifdef __MIPSEB__ move v0, a0 #else srl v1, a0, 24 # v1 = 0x00000011 sll v0, a0, 24 # v0 = 0x44000000 or v0, v0, v1 and v1, a0, 0xff00 sll v1, v1, 8 # v1 = 0x00330000 or v0, v0, v1 srl v1, a0, 8 and v1, v1, 0xff00 # v1 = 0x00002200 or v0, v0, v1 #endif j ra END(ntohl)
Это ваша реализация или взяли откуда-то? Код конечно более компактный - 9 команд вместо моих 13, но видимо без двух дополнительных регистров не обойтись. Здесь так-же как и у меня используются v0-v1 помимо a0.
savigm С одним дополнительным регистром можно сделать примерно так: Код (Text): T=A>>8; T^=A; T&=0xFF00FF; A^=T; T<<=8; A^=T; T=A>>16; A<<=16; A|=T;
Для временного пользования изначально существует регистр at (assembler temporary), а во второй (современной) версии MIPS32 появилась комманда wsbh - своеобразный byte swap.
Да, я вчера тоже до этого докопался из исходников ядра linux - /usr/src/linux/include/asm-mips/byteorder.h. Есть две команды, которые все делают: wsbh и rotr. Код (Text): lw t0, 0(a1) /* Read word value */ wsbh t0, t0 /* Convert endiannes of the halfwords */ rotr t0, t0, 16 /* Swap the halfwords within the words */ Это лучший вариант, но мне он увы не подходит, т.к. это команды MIPS32 Release 2, а я работаю с Release1, т.е. для меня лучшим вариантом будет тот, что предложил думаю вопрос можно считать решенным.
Код (Text): ;a0=11223344 srl v0,a0,8 or v0,v0,0xFF00 xor v0,v0,0xFF00;00110033 or a0,a0,0xFF00 xor a0,a0,0xFF00 sll a0,a0,8;22004400 or a0,a0,v0;22114433 srl v0,a0,16 sll a0,a0,16 or v0,v0,a0;44332211
Откуда вообще взялось такое "странное" требование? Имея в распоряжении десятки регистров, пользоваться одним-двумя (IMHO) неразумно - ложные зависимости будут тормозить конвейер!