| View previous topic :: View next topic |
| Author |
Message |
manc Grandmaster Cheater
Reputation: 1
Joined: 16 Jun 2006 Posts: 551
|
Posted: Sun Sep 23, 2012 8:33 pm Post subject: Counting 1's in a binary number, machine language |
|
|
Say I had a binary number stored in a register, 1010101010111101, for example. If I wanted to clear bit 3 of any binary number(make it 0 if it isn't already), how could I do this in the least amount of instructions/opcodes? I'm not even sure what opcodes I could/should use to accomplish this (LDR,STR,AND,ADD,NOT,JMP, etc). This is theoretical LC-3 machine language (for understanding processor language/architecture), close to assembly I guess. Any input is appreciated.
EDIT: Updated / new question below
_________________
Last edited by manc on Thu Sep 27, 2012 2:45 pm; edited 2 times in total |
|
| Back to top |
|
 |
Dark Byte Site Admin
Reputation: 471
Joined: 09 May 2003 Posts: 25842 Location: The netherlands
|
Posted: Mon Sep 24, 2012 3:30 am Post subject: |
|
|
OR the value with "NOT 8"
16 bit register: fff7
32 bit register: fffffff7
_________________
Do not ask me about online cheats. I don't know any and wont help finding them.
Like my help? Join me on Patreon so i can keep helping |
|
| Back to top |
|
 |
manc Grandmaster Cheater
Reputation: 1
Joined: 16 Jun 2006 Posts: 551
|
Posted: Thu Sep 27, 2012 12:10 am Post subject: |
|
|
Ah, masking, I see now. New question, if you happen to check this thread again:
I'm trying to take the value stored at x3030 and count how many of the bits are 1's, and then store that number at x3031. For example, 1111 0000 1010 0001 has 7 1's, so 0111 would be stored at x3031. I've figured out how to isolate each bit, check for 1's, and increment the counter if there is a 1. However, I'm having trouble stopping my loop.
My initial hope was that the mask would be incremented until it reached 1111 1111 1111 1111, and then when NOT'd, it would become 0. My hope was that this would end the loop....but the result isn't 0. It overflows and becomes negative...which ruins the logic of my program.....Any thoughts?
_________________
Last edited by manc on Thu Sep 27, 2012 10:04 pm; edited 1 time in total |
|
| Back to top |
|
 |
Dark Byte Site Admin
Reputation: 471
Joined: 09 May 2003 Posts: 25842 Location: The netherlands
|
Posted: Thu Sep 27, 2012 4:05 am Post subject: |
|
|
easiest and most straightforward method:
Set counter (R6) to 0
Set Mask (r4) to 1
RepeatThis:
Check if Value (R7) AND Mask (R4) (binary compare) is bigger than 0
If so, increase Counter (r6)
Shift mask(R4) by 1 bit to the left
If Mask is <=1 (OverFlow) goto EndOfLoop (<=1 because some cpu's don't move the last bit back to the first bit, so it turns 0 then)
Goto repeatThis
EndOfLoop:
Counter now contains the number of bits
_________________
Do not ask me about online cheats. I don't know any and wont help finding them.
Like my help? Join me on Patreon so i can keep helping
Last edited by Dark Byte on Fri Sep 28, 2012 3:43 am; edited 1 time in total |
|
| Back to top |
|
 |
manc Grandmaster Cheater
Reputation: 1
Joined: 16 Jun 2006 Posts: 551
|
Posted: Thu Sep 27, 2012 2:36 pm Post subject: |
|
|
| Quote: | | If Mask is <=1 (OverFlow) goto EndOfLoop (<=1 because some cpu's don't move the last bit back to the first bit, so it turns 0 then) |
So I goto EndofLoop only if its negative or zero, correct? I have to set the nzp bits , so 110 right?
Just checking because <=1 includes negatives, 0, and a positive (1), so that would be 111 and would always be triggered.
Lastly, I'm not seeing how (MASK OR VALUE) being positive indicates that the bit is a 1 ? I'm representing my OR this way : (A v B) = ~(~A ^ ~B)
_________________
Last edited by manc on Thu Sep 27, 2012 2:56 pm; edited 1 time in total |
|
| Back to top |
|
 |
Dark Byte Site Admin
Reputation: 471
Joined: 09 May 2003 Posts: 25842 Location: The netherlands
|
Posted: Thu Sep 27, 2012 2:51 pm Post subject: |
|
|
Let's assume 8 bits:
First iteration: Mask is 00000001
Second Iteration: Mask is 00000010
3: 00000100
...
7: 10000000
8: 00000001 (or 00000000 depending on what instruction you used, rotate or shift)
And no, <=1 does not include negatives. This is an unsigned compare
Another way to read: If 0 or 1
_________________
Do not ask me about online cheats. I don't know any and wont help finding them.
Like my help? Join me on Patreon so i can keep helping |
|
| Back to top |
|
 |
manc Grandmaster Cheater
Reputation: 1
Joined: 16 Jun 2006 Posts: 551
|
Posted: Thu Sep 27, 2012 3:54 pm Post subject: |
|
|
I attempted to recreate your suggestion. Did I mess something up horribly, because it sure isnt working? I'm working with 16 bit values btw..
_________________
Last edited by manc on Thu Sep 27, 2012 10:04 pm; edited 1 time in total |
|
| Back to top |
|
 |
Dark Byte Site Admin
Reputation: 471
Joined: 09 May 2003 Posts: 25842 Location: The netherlands
|
Posted: Thu Sep 27, 2012 4:47 pm Post subject: |
|
|
You must not combine the two scripts
One is for clearing a bit, and the other is to count bits
Do them after eachother. Not at the same time (First get the value, then count the bit of that value)
_________________
Do not ask me about online cheats. I don't know any and wont help finding them.
Like my help? Join me on Patreon so i can keep helping |
|
| Back to top |
|
 |
manc Grandmaster Cheater
Reputation: 1
Joined: 16 Jun 2006 Posts: 551
|
Posted: Thu Sep 27, 2012 8:08 pm Post subject: |
|
|
I figured it out. Got it working. Thank you Dark Byte!
_________________
|
|
| Back to top |
|
 |
SteveAndrew Master Cheater
Reputation: 30
Joined: 02 Sep 2012 Posts: 323
|
Posted: Thu Sep 27, 2012 11:18 pm Post subject: |
|
|
I got it working using AND against the unchanged value each time, on each pass of the mask shifting to the left.
when I tried:
| Code: |
shl ebx,1
cmp ebx,1
jle AllBitsCounted //jump if less than or equal to 1 same as jng and should test for 1 or 0 like you said
jmp RepeatThis
|
whether I used a rol ebx,1 or the shift instruction instead, it for some reason returns early, when the mask register is equal to 0x80000000 or 0x8000 (with the 32-bit and 16bit script respectively) which is binary:
10000000000000000000000000000000 (for 32bit) and
1000000000000000 (for 16bit)
which does not make sense to me! It's getting stuck at the last bit and calling that less than or equal to 1... Why is it doing that? If I let it shift left 1 more time I get 0 like you said (for some cpus), or if I use the rotate "rol ebx,1" instead I can use je rather than jle/jng as it rotates that last bit back to the first position (That's true for all CPU's right? I guess I can just use rotate instead then)
EDIT: I figured that one out! I was using the signed conditional jumps (jle/jng/etc) rather than the unsigned ones (jbe/jna/etc) and the most significant bit was being interpreted as a negative... I can now use the shift left rather than rotate as I'm doing an unsigned compare now!
Thanks Dark Byte!
| manc wrote: | I figured it out. Got it working. Thank you Dark Byte!  |
EDIT: Oh looks like you already got it working for you! But my help was not for nothing as I had questions too but they've been answered! LOL
@manc check it out I made a 32-bit and then a 16bit script (since you said you were working with 16 bit)
One question though manc, why are you writing assembler in binary? (the binary to the left of your code descriptions) What kind of system are you assembling for? lol
Value in the script is set to: 0x1337 which is : 1001100110111
It returns 8 in the 'Result' address which is the number of set bits in that number. Change to any number you wish and it still gives the proper result
EDIT: Fixed to use JBE/JNA instead of JLE/JNG so we are now doing an unsigned compare to 0 or 1! (And switched back to shift left instead of rotate left)
| Code: |
//Bit Counter (Dark Bytes Way) 32bit
//Steve Andrew
[enable]
alloc(CountTheBits,64)
label(RepeatThis)
label(BitNotSet)
label(AllBitsCounted)
label(Value)
label(Result)
registersymbol(CountTheBits)
registersymbol(Result)
createthread(CountTheBits)
CountTheBits:
//jmp CountTheBits //just incase you want to step through it uncomment this then nop it after going to "CountTheBits"
xor ecx,ecx //counter
mov ebx,1 //mask
RepeatThis:
mov edx,[Value] //value
and edx,ebx
jz BitNotSet
inc ecx
BitNotSet:
shl ebx,1
cmp ebx,1
jbe AllBitsCounted
jmp RepeatThis
AllBitsCounted:
mov [Result],ecx //Result contains number of bits in 'Value' after this line is executed
ret //end the thread and return
Value:
dd 1337
Result:
dd 0
[disable]
dealloc(CountTheBits)
unregistersymbol(CountTheBits)
unregistersymbol(Result)
|
And the 16 bit version (essentially the same)
Value is 0x539 which is : 10100111001
which is 6 set bits, and it also gets that correctly!
0x539 is also 1337 decimal
| Code: |
//Bit Counter (Dark Bytes Way) 16bit
//Steve Andrew
[enable]
alloc(CountTheBits,64)
label(RepeatThis)
label(BitNotSet)
label(AllBitsCounted)
label(Value)
label(Result)
registersymbol(CountTheBits)
registersymbol(Result)
createthread(CountTheBits)
CountTheBits:
//jmp CountTheBits
xor cx,cx //counter
mov bx,1 //mask
RepeatThis:
mov ax,[Value] //value
and ax,bx
jz BitNotSet
inc cx
BitNotSet:
shl bx,1
cmp bx,1
jbe AllBitsCounted
jmp RepeatThis
AllBitsCounted:
mov [Result],cx //Result contains number of bits in 'Value' after executed
ret //end the thread and return
Value:
dw 539
Result:
dw 0
[disable]
dealloc(CountTheBits)
unregistersymbol(CountTheBits)
unregistersymbol(Result)
|
_________________
Last edited by SteveAndrew on Fri Sep 28, 2012 3:26 pm; edited 1 time in total |
|
| Back to top |
|
 |
Dark Byte Site Admin
Reputation: 471
Joined: 09 May 2003 Posts: 25842 Location: The netherlands
|
Posted: Fri Sep 28, 2012 3:23 am Post subject: |
|
|
Yeah, it's a typo. I meant AND
_________________
Do not ask me about online cheats. I don't know any and wont help finding them.
Like my help? Join me on Patreon so i can keep helping |
|
| Back to top |
|
 |
SteveAndrew Master Cheater
Reputation: 30
Joined: 02 Sep 2012 Posts: 323
|
Posted: Fri Sep 28, 2012 3:28 pm Post subject: |
|
|
Ah yes that's what I figured! Well manc got it working for him, and I got it working for me so yea thanks Dark Byte!
_________________
|
|
| Back to top |
|
 |
manc Grandmaster Cheater
Reputation: 1
Joined: 16 Jun 2006 Posts: 551
|
Posted: Sat Sep 29, 2012 4:41 pm Post subject: |
|
|
| Quote: | | One question though manc, why are you writing assembler in binary? (the binary to the left of your code descriptions) What kind of system are you assembling for? lol |
Not really assembling for any system atm, its just a theoretical 16 bit system / program for the purpose of learning.
Writing my binary code in this:
and then loading it into memory to view it like this:
Its just what I'm learning at university right now. I'm just learning the basics of machine language and moving upwards. Just getting familiar with registers and cpu architecture/ISA/whatever by stepping through memory and seeing the registers/PC/IR/codes change and stuff. Now I'm moving onto assembly...I think the point was to make us appreciate assembly after seeing how annoying doing it all in binary is. I found this forum when I was like 15 for MapIeStory hax...and when I saw the memory viewer and stuff...I became entranced with programming lol. Now here I am 5 years later studying Computer Science at a prestigious uni. So Thanks for that Dark Byte
_________________
|
|
| Back to top |
|
 |
|