Powerpc Assembly – part 2 (Bubble Sort)

Continuando a parlare di Assembly, stavolta voglio mostrare come è possibile implementare un bubble sort con poche istruzioni assembly.
Per chi dispone di un’architettura x86 o non PPC,ricordo che sono diffusi diversi emulatori powerpc open,tra cui PearPc.

Dedico questo codice ad una “certa” categoria di professori…
(Chi vuol capir capisca)


.data
vec:	.long 9          #il nostro vettore di interi disordinati
 .long 2          #ogni intero è 4 byte,cioè una word in un'architettura ppc 32bit
 .long 122
 .long 12
 .long 23
 .long 213
 .long 14539
 .long 121
 .long 42
 .long 12314
end_vec:                        #inserisco un'etichetta qui per calcolare la dimensione del vettore
 .align 2              #allineo il campo dati con la word (anche se non ce n'è bisogno,avendo a che fare solo con una word per ogni intero)

.text                             #segmento codice
 .globl main

main:
 stwu 1,-32(1)          #allocazione dello stackpointer e del LR nello stack
 mflr 0
 stw  0,28(1)
 #siamo ancora nel main #(bubble non ha un suo stackframe)

bubble:
 li 3,4         #  sizeof(long)->r3

	lis  6,vec@ha        #vec -> r6
     addi 6,6,vec@l

	lis 7,end_vec@ha       #end_vec ->r7
     addi 7,7,end_vec@l

	sub 7,7,6          # vec - end_vec ->r7
        divwu 7,7,3       #r7= r7 / sizeof long
                         #cioè la dim. del vettore
       mr 31,7          #dim(vec) -> r31
       mr 7,6            #copia di r6 in r7,utilizzo tale vettore per ripristinare r6 ad ogni ciclo

	subi 31,31,1     #dim(vec)-1 -> r31
                          #nel primo ciclo effettueremo dim-1 confronti
                          #r31 è il counter esterno 'i'

             li 30,0            #0  ->r30
                                 # r30 è il counter interno 'j'

bubble_inner_loop:
 	   addi  30,30,1   #j++
 	   lwz 4,0(6)      # vec[0]->r4
 	   lwz 5,4(6)      # vec[1]->r5

           cmpw 7,4,5        #if(vec[0] < vec[1])
 	   blt 7,next      #salta a next (non effettua lo swap)

swap:			       #altrimenti effettua lo swap
            stw 5,0(6)        #riposiziono in memoria i due interi
            stw 4,4(6)        #invertendo la posizione

next:                 #preparo i registri per il prossimo confronto

	   addi  6,6,4   #vec++ incremento il puntatore
 	   cmpw  6,30,31            #if(j != i)
 	   bne 6,bubble_inner_loop    #continuo col ciclo interno

bubble_extern_loop:       #else...

	   li   30,0                  #j=0
 	   subi 31,31,1            #i--
 	   mr 6,7                    #ripristino vec
           cmpwi  5,31,0          #if (i !=0)
 	   bne 5,bubble_inner_loop #rieffettuo il ciclo interno

end:
 	 lwz 0,28(1)              #riprendo il contenuto di LR dallo stack
 	 stw 1,32(1)              #cancello lo stackframe del main
         mtlr 0                           #riposiziono LR col suo valore originale
 	 blr                           #salto all'indirizzo di ritorno del main

Lascia una Risposta