Shift oddities

Most of the x86 instructions will automatically alter the flags depending on the result. Sometimes this is rather frustrating because you actually what to preserve the flags as long as possible, and sometimes you miss a “mov eax, ecx” which alters the flags. But at least it’s guaranteed that an instruction either sets the flags or it doesn’t touch them, independent of the actual operation… Or is it?

There is the familiy of shift instructions. A “shl eax, cl” will *only* set the sign/zero flags according to the result if cl != 0 (mod 32). Why would anyone want that? Can someone think of a not so artificial situation, where this is useful? And I’m quite sure it is harder to design a processor which handles this special case correctly (let alone pipeline considerations).

Because of this odd behavior, a compiler has to translate

if (a >> b) this(); else that();

to something like

shr eax, cl
test eax, eax
jz bla

And BTW, the rotate instructions never alter the SF/ZF flags.

10 thoughts on “Shift oddities”

  1. With ‘sometimes you miss a “mov eax, ecx” which alters the flags’ I meant: There is no mov which alters the flags, but it would be nice to have such an instruction.

  2. You have to remember that this instruction is from the 1980’s. The 8086 was a “true” CISC processor. As far as I remember, the variable shift instruction was actually implemented by doing a single bit shift “cl” times in a loop. Considering that, it’s easy to see how the flags would not change for a zero shift count.

    Modern processors do variable shifts with barrel shifters in a single step. This takes a lot more transistors than were on the 8086.


  3. myria, you might be right. The acient implementation of shl x, cl used the already available shl x, 1 instruction:

    For (int i=0; i Reply

  4. grr… wordpress destroys “less-than”-operators. The for-loop is meant to run as long as i is less than cl. And ‘ancient’ misses an ‘n’.

  5. Hmm, sorry, the link doesn’t say it all 🙂
    I wanted to post a reply to division problem – sorry, this can be deleted

  6. 1970s processors, such as the 8086, are pretty different from 1980s processors, such as the 80286. The former, for example, have no illegal instruction exception handler, while the latter have one.


Leave a Comment