While reading a tut I saw in the code that the value in eax was divided by SHR 16. So I looked at Mnemonics to see what it exactly does but I didn't understand. Please anyone explain it with examples. thanks, ps: when i changed the value to 10 (i.e SHR 10) the program still works but when I changed it to 100 it crashes.
It all comes down to binary really! take the following: al = 04h = 00000100 (binary) SHL (SHift Left) does just that shifts the binary value left n places, and stuffing with zeros so: SHL al, 1 al = 0x08 = 00001000 (binary). This is the same as multiplying by 2^n so: SHL 04h, 2 = 10h (04h * 2^2!). Shifting right (SHR) is the same a dividing by 2^n Be careful though, bits fall off the end, so: SHL 10000000 (binary), 1 = 0! The value of n is obviously restricted by the size of the thing you are shifting (max - eax: 31, ax: 15, ah/l: 7), you should be able to go higher, but the result will always be 0 as every bit will have been pushed off the end! There are also rolls (ROR, and ROL (roll left and right)) which are similar, but bits are looped back around to the beginning. I don't have the op code help here and can't remember the others... Does SH(L/R) effect the Carry flag? Mirno
Mirno, Yes it does like this: shl ebx,1 ;Times 2 EAX adc eax,00 ;add carry if any This add 1 to eax in case when bits fall off the end. John
Just a reminder about 186+ CPU's. When using shift the shift cannot be higher than 31. The CPU takes a modulo 32 of the count value and uses that for the count. The same might apply for the rotate opcodes as well. Check the intel docs to be sure.
I think your right O@D, but it doesn't make sense to shift (or roll) more than 31 (or 15 or 7 where appropriate (and possibly 63 when AMD get their act together!)), because it would only leave 0! The only time you might want to shift by upto 32 would be to check carry, but there are ways around this! e.g. shl eax, cl .IF ?CARRY ... Some code ... .ENDIF would need to become .IF cl == 32 and eax, 1 ;Clear all but the first bit shr eax, 1 ;Shift last bit into the carry .ELSE shl eax, cl .ENDIF .IF ?CARRY ... Some code ... .ENDIF A little clumsy, but it would work if you needed the CARRY flag! But if Intel limit us to shifts of upto 31 bits there isn't any other way is there? :( But we've sort of lost the plot of the original post anyway :P Mirno
Actually I can think of one instance where I would want to try to shift by more than 32. That is when you are trying to detect the difference between a 8086/8088 and a 80186+/80188+ processor. the 8086/8088 will allow the 32+ bit shift and the others will not. If you give the AX register a value of 1 and shift by 32 the 8086 will have zero in AX where the 80186 will still have the original value of 1.