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.
F9 stc
D1 D9 rcr ecx,1
3 bytes - as long as you don't care about the other 31 bits... :bg
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.
4 bytes:
004010DF B1 1F MOV CL,1F
004010E1 D3E1 SHL ECX,CL
Paul.
or ecx, 80000000h
only bit 31 is set for sure, all other bits retain their previous state.
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.
B180 mov cl,80h
0FC9 bswap ecx
four bytes, lower three bytes untouched
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.
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
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.
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"
will this work ?
33 C9 XOR ECX,ECX
49 DEC ECX
This code will result in 0FFFFFFFFh, not 80000000h
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
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.
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
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.
LimoDriver,
Right you are. Works for all registers too. Sometimes when we try to be tricky, we overlook the obvious. Ratch
Of course it would work for all registers! What a strange statement.
Paul
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
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
?
Why not
mov ebx, 12872h
cli
aad
hlt
lodsw
Because ... it doesn't WORK! :wink
mercifier,
That would work only if the upper three bytes of ECX were zero.
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
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.
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.