looking for smallest code to set only the 31st bit of a 32 bit reg

Started by ThoughtCriminal, April 01, 2007, 04:53:17 AM

Previous topic - Next topic

ThoughtCriminal

Two 6 byte ways:

xor ecx,ecx
0040108D 33 C9            xor         ecx,ecx
bts ecx,31 ;//clear ecx and set to 80000000h
0040108F 0F BA E9 1F      bts         ecx,1Fh

or

xor ecx,ecx
0040108D 33 C9            xor         ecx,ecx
mov cl,1
00401098 B1 01            mov         cl,1
ror ecx,1
0040109A D1 C9            ror         ecx,1


I'm not looking for the fastest, just the smallest way.

Thanks.

sinsi

  F9               stc
  D1 D9            rcr ecx,1

3 bytes - as long as you don't care about the other 31 bits... :bg
Light travels faster than sound, that's why some people seem bright until you hear them.

LimoDriver

Both


0040108D 33 C9            xor         ecx,ecx
0040108F 0F BA E9 1F      bts         ecx,1Fh


and


0040108D 33 C9            xor         ecx,ecx
00401098 B1 01            mov         cl,1
0040109A D1 C9            ror         ecx,1


don't make sense, since you're taking up 6 bytes - a single "mov ecx, 80000000h" is 5 bytes.

On a side note, if you want to place a byte into a register (from 00000080 to 0000007F ), you can do a push / pop.

It's one byte cheaper then xor / mov:


push    1
pop     ecx
ror     ecx, 1


... another 5 bytes faliure:


mov     cl, 1
shl     ecx, 31


and last, but not least, and certianly the fastest 5 byte way:


mov     ecx, 80000000h


The way I see it, the only way you're gonna do this in 4 bytes is to place the following code


xor     ecx, ecx
rcr     ecx, 1


after a code section that always set the carry flag.

dioxin

4 bytes:
004010DF   B1 1F            MOV CL,1F
004010E1   D3E1             SHL ECX,CL

Paul.

dsouza123

or  ecx, 80000000h

only bit 31 is set for sure, all other bits retain their previous state.

LimoDriver

Quote from: dioxin on April 01, 2007, 11:25:47 AM
004010DF   B1 1F            MOV CL,1F
004010E1   D3E1             SHL ECX,CL


You. Are. A. Genius.

dsouza123


B180                   mov     cl,80h
0FC9                   bswap   ecx


four bytes, lower three bytes untouched

dsouza123

If it was bit 30 as the only bit set

two variations, both 5 bytes


  mov   eax, 40000000h     ; the direct way




  push  40h
  pop   eax
  bswap eax


A push of a value of 127 or less takes only 2 bytes, but 128 and greater takes 5 bytes.

LimoDriver

Quote from: dsouza123 on April 01, 2007, 12:18:21 PM

0FC9                   bswap   ecx

four bytes, lower three bytes untouched

bswap will mess up the lower three bytes... 012X = X210

dsouza123

Good catch Limodriver

That is true except if the value was already 80000080h. :red

I was thinking about the code I had just ran through OllyDebug
it already had ecx with 80000000h before the two instructions,
so once cl was 80h, ecx didn't change.



sinsi

Topic: looking for smallest code to set only the 31st bit of a 32 bit reg

Does this mean "value=80000000h" or "leave bits 0-30 the same"
Light travels faster than sound, that's why some people seem bright until you hear them.

OldTimer

will this work ?
33 C9   XOR ECX,ECX
49        DEC ECX

EduardoS


OldTimer

You're quite right, but bit 31 was turned on (so were all the others). 
It's pretty hard to get past dsouza123's suggestion  (  or ecx,80000000h  )
This one is 5 bytes.
D1E1   SHL ecx,1
F9       STC
D1D9   RCR ecx,1

LimoDriver

Well, from the code that ThoughtCriminal posted, it should be pretty obvious that he doesn't need to just set the bit, but he actually wants the number 80000000h in his register.

From what I've seen, dioxin's quite brilliant solution is the shortest way to do just that - put 80000000h in ecx.