The BSWAP instruction is very handy when you want to convert a big endian value to a little endian value and vice versa. Instead of reversing the bytes yourself with a few moves (or shifts, depends how you implement it), a single instruction will do it as simple as that. It personally reminds me something like the HTONS (and friends) in socket programming. The instruction supports 32 bits and 64 bits registers. It will swap (reverse) all bytes inside correspondingly. But it won’t work for 16 bits registers. The documentation says the result is undefined. Now WTF, what was the issue to support 16 bits registers, seriously? That’s a children’s game for Intel, but instead it’s documented to be undefined result. I really love those undefined results, NOT.
When decoding a stream in diStorm in 16 bits decoding mode, BSWAP still shows the registers as 32 bits. Which, I agree can be misleading and I should change it (next ver). Intel decided that this instruction won’t support 16 bits registers, and yet it will stay a legal instruction, rather than, say, raising an exception of undefined instruction, there are known cases already when a specific destination register can cause to an undefined instruction exception, like MOV CR5, EAX, etc. It’s true that it’s a bit different (because it’s not the register index but the decoding mode), but I guess it was easier for them to keep it defined and behave weird. When I think of it again, there are some instruction that don’t work in 64 bits, like LDS. Maybe it was before they wanted to break backward compatibility… So now I keep on getting emails to fix diStorm to support BSWAP for 16 bits registers, which is really dumb. And I have to admit that I don’t like this whole instruction in 16 bits, because it’s really confusing, and doesn’t give a true result. So what’s the point?

I was wondering whether those people who sent me emails regarding this issue were writing the code themselves or they were feeding diStorm with some existing code. The question is how come nobody saw it doesn’t work well for 16 bits? And what’s the deal with XCHG AH, AL, that’s an equal for BSWAP AX, which should work 100%. Actually I can’t remember whether compilers generate code that uses BSWAP, but I am sure I have seen the instruction being used with normal 32 bits registers, of course.

5 Responses to “A BSWAP Issue”

  1. Peter Ferrie says:

    It’s not exactly true to say that it doesn’t work. It does work, but not in the way that you might expect. It still swaps in the high 16 bits of the register, but which is of course 0 in 16-bit mode. :-)
    btw DOSBox needs to be fixed regarding that, since it swaps in the high 16 bits from the 32-bit register.

  2. arkon says:

    Well, originally in diStorm the operand was either a 32 or 64 bits register. Now I also support 16 bits. It’s still misleading. Beat me.

    Also a friend suggested it might be good for obfuscated code and the like.

  3. jabba says:

    bswap di => rol di, 8

  4. mov wtf, 0 says:

    XCHG ah, al ; 16-bit byte swap. Not hard at all.

  5. Dave says:

    Funny how you say it reminds you of the HTONS command… the HTONS ( and friends) command actually use this assembly instruction.

Leave a Reply