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]