PowerPC assembly

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.

Dopo aver capito meglio il funzionamento dello stack e dei registri di uso speciale, ho scritto qualcosina a mano anche io:


#Hello world stampato dalla funzione HELLO
.data
MSG:    .string "Hello World!!\n"
        len = . -MSG    #len è dato dalla differenza tra la locazione corrente e la locazione di MSG
.text
        .align 2
        .globl main
HELLO:
        li 0,4          #in R0 va il riferimento della system call,la n°4 è write
        li 3,1          #in R3 va il primo parametro, 1 è l'identificatore dello stdout
        lis 4,MSG@ha             #carico i 16 bit più significativi dell'indirizzo della stringa su R4
                                           #con lis li shifto di mezza parola a sinistra
        addi 4,4,MSG@l  #piazzo i 16 bit meno significativi di MSG su R4
        li 5,len        #piazzo il terzo parametro cioè la lunghezza della stringa in R5
        sc              #chiamo la system call n° 4
        blr             #ritorno al main

main:
        stwu 1,-16(1)    #R1 è lo stack pointer,avanzo lo stack pointer di 16 bytes,nei primi 4 bytes alloco l'R1 vecchio
        mflr 0          #carico in R0 il linkregister, in esso vi è l'indirizzo di ritorno del main,mi serve per uscire
        stw 0 ,12(1)    #inserisco una copia di lr sullo stack
        bl HELLO        #passo alla funzione HELLO e carico sul lr
                                #l'indirizzo di ritorno,cioè la locazione successiva
        lwz 0 ,12(1)    #ritornando dalla funzione riprendo l'indirizzo
                                 #di ritorno del main dallo stack e lo pongo in R0
        mtlr 0          #rimetto l'indirizzo in lr
        addi 1,1,16     #chiudo lo stack del main
        blr             #salto all'indirizzo di ritorno ed esco

#Spawn di un processo 

.data
 file:
 	.string "/usr/bin/gcalctool"
 error:
 	.string "Errore ci fù!"
 	.align 2
.text 

	.globl main
 .align 2

main:
 stwu 1,-20(1)   #creo lo stackframe del main
 mflr 30
 stw  30,4(1)    #pongo lr nello stack
 stw  3,8(1)
 stw  4,12(1)
 stw  5,16(1)   #come anche i 3 parametri

	bl spawn

	lwz 30,4(1)     #recupero lr
 lwz 3,8(1)
 lwz 4,12(1)
 lwz 5,16(1)     # e i parametri 

	mtlr 30
 blr  

spawn:
 stwu 1,-20(1)         #creo lo stack frame della funzione spawn
 mflr 30
 stw 30,4(1)           #e vi pongo i parametri del main passati alla spawn
 stw 3,8(1)
 stw 4,12(1)
 stw 5,16(1)

	li 0,2		      #kernel fork pronta
 sc
 cmpwi 7,3,0   #confronto il valore di ritorno della fork con 0 ponendo in cr[7] l'esito
 beq 7,son      #se è uguale a 0 sono il figlio
 addi 1,1,20    #chiudo lo stackframe
 blr            #altrimenti torno al main

son:
 li 0 ,11                   #sono il figlio e quindi effettuo l'exec
 lis 3,file@ha
 addi 3,3,file@l

	lwz 30,4(1)     #recupero lr
 lwz 4,12(1)
 lwz 5,16(1)     # e i parametri
 sc

	lis 3,error@ha       #in caso di mancata esecuzione della exec
 addi 3,3,error@l
 b puts               #stampo un errore
 blr                  #e torno al main

Una Risposta a “PowerPC assembly”

  1. Andrea Dice:

    Molto utile! Chiaro e completo… erano mesi che cercavo degli esempi come questi!

    Grazie!

Lascia una Risposta