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

PowerPC assembly

12 Febbraio 2008

Essendo uno degli ultimi possessori di un processore della famiglia PowerPC non potevo resistere alla tentazione di scoprire le caratteristiche interne di questa meravigliosa macchina.
Il processore appartiene alla famiglia RISC,cioè ha un set di istruzioni limitato nelle funzionalità,(load and store), presenta un banco di 31 registri in virgola fissa a 32 bit e un banco di 32 registri in virgola mobile a 64 bit e alcuni registri di uso speciale.

In giro si trova parecchio materiale a riguardo,ho trovato un paio di references : semplificata
ed estesa
ma scarseggiavano un pò gli esempi e il codice.
Con il compilatore gcc però si può effettuare la compilazione senza assemblare il programma in codice eseguibile, adoperando

 gcc -S -o programma nomesorgente.c

e grazie a questo, è possibile studiare semplici programmi scritti ad alto livello e tradotti in assembly.
Leggi il seguito di questo post »