flat assembler
Message board for the users of flat assembler.

Index > Main > Clearing leftmost set bit?

Author
Thread Post new topic Reply to topic
bitshifter



Joined: 04 Dec 2007
Posts: 796
Location: Massachusetts, USA
bitshifter 14 Jun 2010, 14:36
This question was asked on another forum...
After pondering it for a while the only solution i have is brute force
To test if leftmost bit is set and clear it with test,then and not's.
Also, no looping can be performed...
But is there such a way i am not aware of?

_________________
Coding a 3D game engine with fasm is like trying to eat an elephant,
you just have to keep focused and take it one 'byte' at a time.


Last edited by bitshifter on 15 Jun 2010, 00:15; edited 1 time in total
Post 14 Jun 2010, 14:36
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20303
Location: In your JS exploiting you and your system
revolution 14 Jun 2010, 14:45
By "leftmost" do you mean most-significant?

Don't forget about BSR and BSF opcodes.
Post 14 Jun 2010, 14:45
View user's profile Send private message Visit poster's website Reply with quote
bitshifter



Joined: 04 Dec 2007
Posts: 796
Location: Massachusetts, USA
bitshifter 14 Jun 2010, 14:48
like input = 11111111b, ouput = 01111111b
Post 14 Jun 2010, 14:48
View user's profile Send private message Reply with quote
ass0



Joined: 31 Dec 2008
Posts: 518
Location: ( . Y . )
ass0 14 Jun 2010, 14:51
Code:
and al, 0x7f;for 8 bits
and ax, 0x7fff ; for 16-bits
xor ecx, ecx
dec ecx
shr ecx, 1
and eax, ecx ;for 32-bits
and eax, 0x7fffffff; also 32-bits but not sure if legal    

too easy

hahaha many times edited =p

_________________
Image
Nombre: Aquiles Castro.
Location2: about:robots


Last edited by ass0 on 14 Jun 2010, 15:06; edited 5 times in total
Post 14 Jun 2010, 14:51
View user's profile Send private message Reply with quote
bitshifter



Joined: 04 Dec 2007
Posts: 796
Location: Massachusetts, USA
bitshifter 14 Jun 2010, 14:52
Could you provide BSR example please
I am new to this instruction...
(For 32bit unsigned integer)
Post 14 Jun 2010, 14:52
View user's profile Send private message Reply with quote
ass0



Joined: 31 Dec 2008
Posts: 518
Location: ( . Y . )
ass0 14 Jun 2010, 14:57
I though you were an intel manual's reader bitshifter

_________________
Image
Nombre: Aquiles Castro.
Location2: about:robots
Post 14 Jun 2010, 14:57
View user's profile Send private message Reply with quote
Tyler



Joined: 19 Nov 2009
Posts: 1216
Location: NC, USA
Tyler 14 Jun 2010, 15:02
You don't even need Intel's manuals. Fasm's has a good example. http://flatassembler.net/docs.php?article=manual#2.1.5

"btr eax,31" clears the 31st bit and sets the flags depending if the bit was already clear or not. It doesn't work on bytes though.
Post 14 Jun 2010, 15:02
View user's profile Send private message Reply with quote
bitshifter



Joined: 04 Dec 2007
Posts: 796
Location: Massachusetts, USA
bitshifter 14 Jun 2010, 15:03
I am, but never had a reason to use those instructions...
*just made print_binary routine to try them out*
Post 14 Jun 2010, 15:03
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20303
Location: In your JS exploiting you and your system
revolution 14 Jun 2010, 15:27
Code:
movzx eax,al
bsr ecx,eax
jz .eax_is_zero
btr eax,ecx    
Finds the MSb that is set and clears it.
Post 14 Jun 2010, 15:27
View user's profile Send private message Visit poster's website Reply with quote
bitshifter



Joined: 04 Dec 2007
Posts: 796
Location: Massachusetts, USA
bitshifter 14 Jun 2010, 15:32
Kick ass!
Thanx revo!
So for 32 bit unsigned integer i can just omit movzx?

This is what i came up with...
(It uses some BIOS functions and some 32 bit registers)
Code:
org 0x0100
use16
        mov     ax,0x0003
        int     0x10

        mov     eax,7
        call    print_binary
        call    print_newline
        call    clear_leftmost_bit
        call    print_binary

        xor     ah,ah
        int     0x16

        ret

print_binary:
        ; EAX = input
        pusha
        mov     ebx,eax
        mov     ecx,32
    @@: xor     al,al
        shl     ebx,1
        adc     al,'0'
        call    print_character
        sub     ecx,1
        jnz     @b
        mov     al,'b'
        call    print_character
        popa
        ret

print_newline:
        push    ax
        mov     al,13
        call    print_character
        mov     al,10
        call    print_character
        pop     ax
        ret

print_character:
        ; AL = character
        pusha
        mov     ah,0x0e
        mov     bh,0x00
        int     0x10
        popa
        ret

clear_leftmost_bit:
        ; Input: EAX = 32bit unsigned integer
        push    ecx
        bsr     ecx,eax
        jz      .is_zero
        btr     eax,ecx
  .is_zero:
        pop     ecx
        ; Output: EAX = 32bit unsigned integer with leftmost bit cleared
        ret
    


Last edited by bitshifter on 14 Jun 2010, 15:48; edited 1 time in total
Post 14 Jun 2010, 15:32
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20303
Location: In your JS exploiting you and your system
revolution 14 Jun 2010, 15:41
bitshifter wrote:
So for 32 bit unsigned integer i can just omit movzx?
Yes.
Post 14 Jun 2010, 15:41
View user's profile Send private message Visit poster's website Reply with quote
Tyler



Joined: 19 Nov 2009
Posts: 1216
Location: NC, USA
Tyler 24 Aug 2010, 05:01
Hmm... should I revive it? Yep.

Bored, nothing to do. I was looking for an old post, but I found this instead. Made me think of this:
Code:
scl ax,1
shr ax,1
    

It clears the left most bit, and leaves it's set-ness in the carry flag.

Ironic how you could've done this with bitshifting Razz.
Post 24 Aug 2010, 05:01
View user's profile Send private message Reply with quote
Madis731



Joined: 25 Sep 2003
Posts: 2139
Location: Estonia
Madis731 24 Aug 2010, 09:43
http://www.jjj.de/fxt/
1.6: Operations on high bits or blocks of a word
1.6.1 Isolating the highest one and fi nding its index
will suggest the same BSR instruction.

@Tyler:
scl + shr combo will yield the same result as shl + shr and they both clear *the leftmost bit* NOT the *leftmost SET bit*

bitshifter needs to have the correct instruction sequence to convert 00001111b to 00000111b. This is what BSR instruction is for.
Post 24 Aug 2010, 09:43
View user's profile Send private message Visit poster's website Yahoo Messenger MSN Messenger Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4624
Location: Argentina
LocoDelAssembly 24 Aug 2010, 13:09
What is scl?
Post 24 Aug 2010, 13:09
View user's profile Send private message Reply with quote
Tyler



Joined: 19 Nov 2009
Posts: 1216
Location: NC, USA
Tyler 24 Aug 2010, 15:21
> scl + shr combo will yield the same result as shl + shr and they both clear *the leftmost bit* NOT the *leftmost SET bit*
I just now got what he meant. I was thinking: clear leftmost bit, and tell whether it was set or not. Embarassed

> What is scl?
I meant rcl, I think.
Post 24 Aug 2010, 15:21
View user's profile Send private message Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4624
Location: Argentina
LocoDelAssembly 24 Aug 2010, 15:38
I suspected so Razz

But note that what RCL does is fill the vacant bit with CF. ROL, RCL and SHL always set CF to the value of the leftmost bit. In your code, once scl is replaced with either SHL or ROL, SHR will always ensure that CF is zero and if RCL was used first then CF will preserve the value prior to executing both instructions.
Post 24 Aug 2010, 15:38
View user's profile Send private message Reply with quote
edfed



Joined: 20 Feb 2006
Posts: 4330
Location: Now
edfed 24 Aug 2010, 15:54
Code:
;eax=number
mov cl,0
@@:
inc cl
add eax,eax ;shl eax,1
jc @f
jne @b
ret
@@:
shr eax,cl
ret
    


something like that.
Post 24 Aug 2010, 15:54
View user's profile Send private message Visit poster's website Reply with quote
Tyler



Joined: 19 Nov 2009
Posts: 1216
Location: NC, USA
Tyler 24 Aug 2010, 18:19
edfed wrote:
Code:
;eax=number
mov cl,0
@@:
inc cl
add eax,eax ;shl eax,1
jc @f
jne @b
ret
@@:
shr eax,cl
ret
    


something like that.
bitshifter wrote:
Also, no looping can be performed...
Post 24 Aug 2010, 18:19
View user's profile Send private message Reply with quote
edfed



Joined: 20 Feb 2006
Posts: 4330
Location: Now
edfed 24 Aug 2010, 18:45
if i read the title, i see:

clear the leftmost set bit (not the most significant bit), without a loop, i don't see how it can be done...

i see that for a dword = 5, the leftmost set bit is bit 2. and is 101b
result will give 1.

for 01001101b, result will be 1101b, and for 111101011b, it will output 11101011b.

to clear the LSB, it is very easy.

shl eax,1
shr eax,1


and eax,80000000h


btc eax,31
Post 24 Aug 2010, 18:45
View user's profile Send private message Visit poster's website Reply with quote
bitRAKE



Joined: 21 Jul 2003
Posts: 4024
Location: vpcmpistri
bitRAKE 25 Aug 2010, 00:42
I play along...

Single register method:
Code:
    stc
@@: rcl rax,1
    jnc @B
    clc
@@: rcr rax,1
    jnbe @B    
Post 25 Aug 2010, 00:42
View user's profile Send private message Visit poster's website Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.