The MASM Forum Archive 2004 to 2012

General Forums => The Laboratory => Topic started by: ThoughtCriminal on April 01, 2007, 04:53:17 AM

Title: looking for smallest code to set only the 31st bit of a 32 bit reg
Post by: ThoughtCriminal on April 01, 2007, 04:53:17 AM
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.
Title: Re: looking for smallest code to set only the 31st bit of a 32 bit reg
Post by: sinsi on April 01, 2007, 05:04:58 AM
  F9               stc
  D1 D9            rcr ecx,1

3 bytes - as long as you don't care about the other 31 bits... :bg
Title: Re: looking for smallest code to set only the 31st bit of a 32 bit reg
Post by: LimoDriver on April 01, 2007, 09:40:51 AM
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.
Title: Re: looking for smallest code to set only the 31st bit of a 32 bit reg
Post by: dioxin on April 01, 2007, 11:25:47 AM
4 bytes:
004010DF   B1 1F            MOV CL,1F
004010E1   D3E1             SHL ECX,CL

Paul.
Title: Re: looking for smallest code to set only the 31st bit of a 32 bit reg
Post by: dsouza123 on April 01, 2007, 11:48:49 AM
or  ecx, 80000000h

only bit 31 is set for sure, all other bits retain their previous state.
Title: Re: looking for smallest code to set only the 31st bit of a 32 bit reg
Post by: LimoDriver on April 01, 2007, 12:09:14 PM
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.
Title: Re: looking for smallest code to set only the 31st bit of a 32 bit reg
Post by: dsouza123 on April 01, 2007, 12:18:21 PM

B180                   mov     cl,80h
0FC9                   bswap   ecx


four bytes, lower three bytes untouched
Title: Re: looking for smallest code to set only the 31st bit of a 32 bit reg
Post by: dsouza123 on April 01, 2007, 12:51:46 PM
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.
Title: Re: looking for smallest code to set only the 31st bit of a 32 bit reg
Post by: LimoDriver on April 01, 2007, 12:56:15 PM
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
Title: Re: looking for smallest code to set only the 31st bit of a 32 bit reg
Post by: dsouza123 on April 01, 2007, 01:26:11 PM
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.


Title: Re: looking for smallest code to set only the 31st bit of a 32 bit reg
Post by: sinsi on April 02, 2007, 09:12:10 AM
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"
Title: Re: looking for smallest code to set only the 31st bit of a 32 bit reg
Post by: OldTimer on April 02, 2007, 11:25:51 AM
will this work ?
33 C9   XOR ECX,ECX
49        DEC ECX
Title: Re: looking for smallest code to set only the 31st bit of a 32 bit reg
Post by: EduardoS on April 02, 2007, 11:31:16 AM
This code will result in 0FFFFFFFFh, not 80000000h
Title: Re: looking for smallest code to set only the 31st bit of a 32 bit reg
Post by: OldTimer on April 02, 2007, 12:06:39 PM
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
Title: Re: looking for smallest code to set only the 31st bit of a 32 bit reg
Post by: LimoDriver on April 02, 2007, 01:48:32 PM
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.
Title: Re: looking for smallest code to set only the 31st bit of a 32 bit reg
Post by: Ratch on April 02, 2007, 02:40:44 PM
ThoughtCriminal,
       MOV AL,080H
  SHL EAX,24


     The above uses 5 bytes, BUT it can be used for EAX,EBX, and EDX too.  Also bit patterns other than 080H can be easily be sent to the leftmost byte.  Ratch
Title: Re: looking for smallest code to set only the 31st bit of a 32 bit reg
Post by: LimoDriver on April 02, 2007, 04:18:22 PM
Am I the only one taking crazy pills?

Whatever happened to MOV ?!


mov e?x, WHATEVER


is ALWAYS 5 bytes!

I like to mov it, mov it.
Title: Re: looking for smallest code to set only the 31st bit of a 32 bit reg
Post by: Ratch on April 02, 2007, 05:04:57 PM
LimoDriver,

     Right you are.  Works for all registers too.  Sometimes when we try to be tricky, we overlook the obvious.  Ratch
Title: Re: looking for smallest code to set only the 31st bit of a 32 bit reg
Post by: PBrennick on April 02, 2007, 05:19:23 PM
Of course it would work for all registers! What a strange statement.

Paul
Title: Re: looking for smallest code to set only the 31st bit of a 32 bit reg
Post by: Ratch on April 02, 2007, 06:05:28 PM
PBrennick,

QuoteOf course it would work for all registers! What a strange statement.

     Is it?  When you consider that the methods submitted by dioxin and I do not?  dioxin's method does not work for EAX,EBX,EDX,EBP,ESI,EDI and mine won't work for EBP,ESI,EDI.  Ratch


Title: Re: looking for smallest code to set only the 31st bit of a 32 bit reg
Post by: mercifier on April 02, 2007, 06:33:17 PM
Quote from: dioxin on April 01, 2007, 11:25:47 AM
4 bytes:
004010DF   B1 1F            MOV CL,1F
004010E1   D3E1             SHL ECX,CL

Paul.


Why not:
            MOV CL,1
            ROR ECX,CL


?
Title: Re: looking for smallest code to set only the 31st bit of a 32 bit reg
Post by: LimoDriver on April 02, 2007, 07:27:09 PM
Why not


mov ebx, 12872h
cli
aad
hlt
lodsw


Because ... it doesn't WORK! :wink
Title: Re: looking for smallest code to set only the 31st bit of a 32 bit reg
Post by: MichaelW on April 02, 2007, 08:05:26 PM
mercifier,

That would work only if the upper three bytes of ECX were zero.
Title: Re: looking for smallest code to set only the 31st bit of a 32 bit reg
Post by: dsouza123 on April 02, 2007, 08:16:36 PM
Dioxin's method though at 5 bytes will work for eax, ebx, ecx, edx


mov  al, 31   ; any odd byte value from 1 to 255 will give the same result
shl eax, 31

mov  bl,  1
shl ebx, 31

mov  cl,  3
shl ecx, 31

mov  dl,  7
shl edx, 31
Title: Re: looking for smallest code to set only the 31st bit of a 32 bit reg
Post by: mercifier on April 02, 2007, 08:41:40 PM
Quote from: MichaelW on April 02, 2007, 08:05:26 PM
That would work only if the upper three bytes of ECX were zero.

You're right. The MSB would be set, but the upper three bytes would just be shifted down one position and unless they were all zeroes, that wouldn't be very useful.
Title: Re: looking for smallest code to set only the 31st bit of a 32 bit reg
Post by: ThoughtCriminal on April 03, 2007, 04:23:37 AM
Wow what Paul offered works exactly as I hoped and 1 byte less than just moving 80000000h into ecx.

My goal was not speed just the smallest code size possible.  I was interesting to see a lot of the less used instructions.

Thanks everyone.