

.method countones(a)
.var
C
.end_var

        BIPUSH 0
        ISTORE C        //inizializza C=0
ciclo:  ILOAD a         //carica X sullo stack
        IFEQ fine       //se a=0 vai a fine (non ci sono bit ad 1)
        ILOAD a
        IFLT neg        //se a<0 vai a neg (bit piu' significativo = 1)
        GOTO L1
neg:    IINC C 1        //incrementa C (perche' c'e' un 1)
L1:     ILOAD a         //inizia operazione  a <- a + a (ovvero left-shift a)
        DUP
        IADD
        ISTORE a
        GOTO ciclo
fine:   ILOAD C         //restituisci il valore contenuto in C come risulato del met
odo
        IRETURN
.end_method


Soluzione proposta da DJGecchi

.method countones(a)
.var
MASK
COUNTER
.end_var

//INIZIALIZZAZIONE VARIABILI
	BIPUSH 0
	ISTORE COUNTER //inizializzo il contatore a 0
	BIPUSH 1
	ISTORE MASK //inizializzo mask a 00000000 00000000 00000000 00000001 

//CONTROLLO DEL BIT
loop:	ILOAD MASK //faccio l?and logico tra l?input del metodo e la mask:
	ILOAD A
	IAND
//in questo modo sullo stack sarà presente 0 se il bit di a nella posizione dell?unico bit della
//mask è 0, o un numero diverso da zero se il suddetto bit è 1
	IFEQ jump //se sullo stack è presente 0 non devo effettuare l?incremento del contatore
	IINC COUNTER 1 //altrimenti il contatore viene incrementato di 1
							
//SHIFT A SINISTRA DI MASK
jump:	ILOAD MASK
	DUP
	IADD //moltiplico per 2 mask: in questo modo è come se effettuassi
	ISTORE MASK //uno shift a sinistra dell?unico bit di mask

//CONTROLLO DI USCITA DAL CICLO
	ILOAD MASK //controllo che la mask non sia arrivata...
	IFEQ fine //...a 00000000 00000000 00000000 00000000
	GOTO loop

//RETURN
fine:	ILOAD COUNTER
	IRETURN //restituisco il contatore
.end_method



Il metodo può essere ottimizzato non utilizzando una variabile mask, ma lasciandola sempre in cima allo stack, risparmiando così alcuni iload e istore

.method countones(a)
.var
COUNTER
.end_var

//INIZIALIZZAZIONE VARIABILI
	BIPUSH 0
	ISTORE COUNTER //inizializzo il contatore a 0
	BIPUSH 1 //inizializzo mask a 00000000 00000000 00000000 00000001 

//CONTROLLO DEL BIT
loop:	DUP //duplico mask
	ILOAD A //faccio l?and logico tra l?input del metodo e la mask:
	IAND
//in questo modo sullo stack sarà presente 0 se il bit di a nella posizione dell?unico bit della
//mask è 0, o un numero diverso da zero se il suddetto bit è 1
	IFEQ jump //se sullo stack è presente 0 non devo effettuare l?incremento del contatore
	IINC COUNTER 1 //altrimenti il contatore viene incrementato di 1
						
//SHIFT A SINISTRA DI MASK
jump:	DUP //moltiplico per 2 mask: in questo modo è come se effettuassi
	IADD //uno shift a sinistra dell?unico bit di mask 

//CONTROLLO DI USCITA DAL CICLO
	DUP //controllo che la mask non sia arrivata...
	IFEQ fine //...a 00000000 00000000 00000000 00000000
	GOTO loop

//RETURN
fine:	ILOAD COUNTER
	IRETURN //restituisco il contatore
.end_method



Se non fosse chiaro, ecco un?implementazione in java:

public int countones(int a)
{
int counter = 0;
      for(int mask = 1 ; mask != 0 ; mask *= 2)
     	if((mask & a) != 0)
 		counter++;
         return counter;
 }





