Powerpc Assembly – part 2 (Bubble Sort)

23 febbraio 2008

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 [/sourcecode]