0

So I need to count bits on a integer this is my code but I don't know why is not working, I sent a hex value from c main and somehow I have to shift it and mask it. I'm kind of lost, I guess I'm getting a wrong answer because I don't know how to shift and mask, But I think I kind of know what I'm doing with the loops and the adding. again I need to count until 32 the bits that are 1 not zeros, but I'm getting a wrong answer, for example 6 110 it would be 2 bits. this is a homework so I cant use a built in function or whatever haha.

   .global hi
hi:

save %sp,-1024,%sp

clr %i0
clr %i1
clr %i2

loop:  

       cmp %i2,32
       be,a away
    mov %l7,%i0
    add 1,%i2,%i2

    and %i0,1,%l1


    cmp %l1,1
    be count
       nop
    !srl %i0,%l2,%10
    !mov %l2,%i0


    !and %i0,1,%i0
    srl %i0,1,%i0

    ba loop
    nop
    !mov %l2,%i0

count:
    add 1,%l7,%l7

away:
    ret
    restore

Why is this not working yet? I followed it that c implementation and still is not returning the number of bits :/. the return value is %i0 and I have no idea how to jump back to the loop after incrementing counter.

So what is this doing? when it says ba loop isn't it supposed to go back to loop?

So I don't know if is much to ask but, do you have any idea of how to fix this issue? :p because I don't really know, I'm looking at the manual and I don't see anything that can help me :/.

David
  • 646
  • 4
  • 14
  • 1
    Unless I misunderstand what you're trying to do, SPARC V9 has a `POPC` instruction for exactly this purpose. – Jerry Coffin Oct 08 '12 at 04:21
  • What I'm trying to do is to count the bits on for example 6 110 it would be 2 bits – David Oct 08 '12 at 04:28
  • this is a homework so I cant use a built in function or whatever haha. – David Oct 08 '12 at 04:29
  • I believe you know how to add and shift, but your control structure has faults: you exit the function immediately after finding the first bit. – Aki Suihkonen Oct 08 '12 at 04:55
  • How comes I exit the function immediately after finding the first bit? how do you know that, because that means I'm not understanding how this really works ... – David Oct 08 '12 at 05:01
  • @user1713352: `popc` isn't a _builtin function_ it's part of the sparcv8+ / sparcv9 instruction set. – FrankH. Oct 08 '12 at 12:09

1 Answers1

0

There are also faults in shifting and adding...

Your loop structure is pretty much as follows:

int count(int data) {
loop_entry:
        if (loop_counter == 32) goto out;      // this is basically ok
        loop_counter++;            

        if (some_math_expression) goto count;  // the math expression is ok

        temporary_variable>>=1;   // this is not ok -- you should be shifting l2 

        if (something_else) goto loop_entry;   // what actually is the 'something_else'?

count:
        data++;    // this is not ok: you are incrementing i0 instead of l2
                   // this is not ok: fall through instead of jumping back to loop

out:
        return result;

}

The proper structure most close to your implementation in C would be

int count (int data)
{
     int result=0;
     int temp=0;
     int loop_counter = 0;
     while (loop_counter++ != 32) {  // conditionally jump out of the loop
         temp = data & 1;
         if (temp == 1) {   // Q: how to perform this in assembler? 
            result++;       // A: negate the condition and jump over the result++
         }                  // statement
         data>>=1;
     }                      // (unconditionally? Jump to beginning of loop)
     return result;
}

http://www.cs.northwestern.edu/~agupta/_projects/sparc_simulator/SPARC%20INSTRUCTION%20SET-1.htm

Here it says that 'ba' = branch always (my mistake) -- If the comparison for (temp == 1) is done by 'be' or branch if equal, then the opposite
of that is branch if not equal, or bne. Thus, the conditional statament would be:

cmp %temp, %one          # I'm using temp & one to "alias" the registers
bne skip                 # that contain these variables or constants
nop    ; // delay slot
add %count, 1, %count
skip:

// there's however a trick to do that without jumping (see the link about 'carry'-bit)
add %data,%data,%data    # "multiply" data by two, which may produce carry
addx %count,%zero,%count # count = count + 0 + carry_produced_by_previous_instruction

Reason to use the carry bit and the overflow bit

Community
  • 1
  • 1
Aki Suihkonen
  • 19,144
  • 1
  • 36
  • 57
  • .global hi hi: save %sp,-1024,%sp clr %i0 clr %i1 clr %i2 loop: cmp %i2,32 be,a away mov %l7,%i0 add 1,%i2,%i2 and %i0,1,%l1 cmp %l1,1 be count nop !srl %i0,%l2,%10 !mov %l2,%i0 !and %i0,1,%i0 srl %i0,1,%i0 ba loop nop !mov %l2,%i0 count: add 1,%l7,%l7 away: ret restore why is this not working yet? I tried to follow that c code and still, shouldnt this return the number of bits on? for example for 6 should return 2 ? – David Oct 08 '12 at 06:14
  • You are still not jumping back to the loop after incrementing the counter. Further: what does your ABI reference manual say about in which register the return value should be placed? Are you sure it's supposed to be %l7? [I don't know] – Aki Suihkonen Oct 08 '12 at 06:29
  • Its %i0 that is the return value – David Oct 08 '12 at 06:32
  • So what is this doing? when it says ba loop isn't it supposed to go back to loop? – David Oct 08 '12 at 06:59
  • So I don't know if is much to ask but, do you have any idea of how to fix this issue? :p – David Oct 08 '12 at 07:06
  • because I don't really know, I'm looking at the manual and I don't see anything that can help me :/. – David Oct 08 '12 at 07:07
  • yes, my mistake: ba is the proper instruction in sparc. I was confused by 10 other assembler dialects. – Aki Suihkonen Oct 08 '12 at 07:51
  • Thanks, you were really helpful, I had no Idea what I was doing here. – David Oct 08 '12 at 08:05