Istruzioni principali e funzioni

In questa lezione vengono descritte le principali istruzioni assembly e viene mostrato come creare e richiamare una funzione. Affronteremo le istruzioni per inizializzare nuove variabili, effettuare dei confronti tra registri e capiremo meglio come scrivere il nostro prmo programma.

Istruzioni assembly

Di seguito sono riportate e descritte alcune istruzioni assembly; nel nostro corso saranno quelle più utilizzate. Il set completo di istruzioni dei processori della famiglia di processori Intel x86 è facilmente reperibile in rete.

Inizializzazione

Move

mov src, dst

Consente l’inizializzazione di un registro o di un’area di memoria. Accetta alcuni suffissi (come l,w, e b) per indicare la dimensione dell’operando src.

Load Effective Address

lea src, dst

Trasferisce l’indirizzo di memoria dell’operando src nell’operando dst.

Confronti e salti

Compare

cmp op1, op2 

Esegue la sottrazione op2 – op1, scarta il risultato ed in base ad esso imposta le flag del registro EFLAGS. Di solito l’istruzione cmp è seguita da istruzioni di salto condizionato che operano in base alle flag impostate da cmp.

Jump if above

ja etichetta 

Salta all’istruzione associata a etichetta se l’istruzione cmp op1, op2 ha verificato che op2 è maggiore di op1.

Jump if below

jb etichetta

Salta all’istruzione associata a etichetta se l’istruzione cmp op1, op2 ha verificato che op1 è maggiore di op2.

Jump if equal

je etichetta

Salta all’istruzione associata a etichetta se l’istruzione cmp op1, op2 ha verificato che op1 è uguale a op2.

Jump if not X

jnX etichetta 

Salta all’istruzione associata a etichetta se l’istruzione cmp op1, op2 ha verificato che op1 non è X di op2. Il carattere X deve essere sostituito da uno tra a (above), b (below), e (equal), ae (above-equal), be (below-equal).

Jump if CX is zero

jcxz etichetta 

Salta all’istruzione associata a etichetta se il registro CX contiene il valore 0.

Jump

jmp etichetta

Salta incondizionatamente alla istruzione associata a etichetta.

Test

test op1, op2 Test.

Eseguito l’AND bit a bit tra gli operandi, scarta il risultato e in base ad esso impostando le flag del registro EFLAGS. A differenza dell’istruzione AND, non memorizza il risultato in modo da poter fare più test in sequenza. L’istruzione test %ax, %ax imposta lo Zero Flag a 1 se e solo se AX è zero.

Loop

loop lbl

Quando il processore incontra questa istruzione, per prima cosa decrementa ECX di 1 e successivamente controlla se ECX è zero; se ECX non è zero allora salta all’istruzione indicata dall’etichetta lbl. Solo ECX si può utilizzare per questa e di conseguenza non è possibile innestare cicli uno dentro l’altro.

Aritmetiche

Increment

inc op

Incrementa di 1 il valore memorizzato in op (op può essere un registro o una locazione di memoria).

Decrement

dec op

Decrementa di 1 il valore memorizzato in op (op può essere un registro o una locazione di memoria)

Somma

add src, dst

Somma a dst il valore di src e memorizza il risultato in dst.

Sottrazione

sub src, dst

Sottrae a dst il valore di src e memorizza il risultato in dst.

Divisione senza segno

div op

Esegue la divisione senza segno. Se l’operando op è un byte il registro AX viene diviso per l’operando, il quoziente viene memorizzato in AL, e il resto in AH. Se l’operando è una word, il valore ottenuto concatenando il contenuto di DX e AX viene diviso per l’operando, i 16 bit più significativi del dividendo devono essere memorizzati nel registro DX, il quoziente viene memorizzato nel registro AX e il resto in DX. La divisione in doppia precisione utilizza EAX ed EDX.

Moltiplicazione senza segno

mul op

Esegue la moltiplicazione senza segno. Se l’operando op è un byte il registro AL viene moltiplicato per l’operando e il risultato viene memorizzato in AH. Se l’operando è una word il contenuto del registro AX viene moltiplicato per l’operando e il risultato viene memorizzato nella coppia di registri DX:AX (DX conterrà i 16 bit più significativi del risultato). La moltiplicazione in doppia precisione utilizza EAX ed EDX.

Logiche

OR esclusivo XOR

xor src, dst

Calcola l’OR esclusivo bit a bit dei due operandi e lo memorizza nell’operando dst.

OR logico

or src, dst

Calcola l’OR bit a bit dei due operandi e memorizza il risultato nell’operando dst.

AND logico
and src, dst

Calcola l’AND bit a bit dei due operandi e lo memorizza nell’operando dst.

NOT logico

not op

Inverte ogni singolo bit dell’operando op.

Gestione dello stack

Push

push src

Memorizza nello stack il valore contenuto nell’operando src.

Pop

pop dest

Estrae il contenuto della locazione di memoria che si trova in cima allo stack e lo memorizza nell’operando dest.

Chiamata a funzione

Call

call op

Memorizza nello stack il valore di ritorno, ovvero l’indirizzo dell’istruzione successiva alla call e trasferisce l’esecuzione alla locazione di memoria referenziata da op (op di solito è un etichetta associata ad una funzione).

Return

ret

Estrae dallo stack il valore di ritorno corrispondente all’indirizzo dell’istruzione da cui riprendere l’esecuzione dopo una chiamata all’istruzione call.

Etichette

Nel linguaggio Assembly non esiste il costrutto IF ... THEN ... ELSE e quindi le istruzioni di salto servono per far saltare l’esecuzione del programma ad una certa istruzione in funzione del valore di una condizione. Le uniche condizioni che si possono valutare sono <,=,> tra due valori numerici e la presenza di zero nel registro ECX. In particolare, la valutazione di una condizione di <,=,> consiste di due istruzioni: la prima sottrae tra loro i due valori numerici e imposta i bit SF e ZF del registro EFLAGS, la seconda effettua il salto in base al valore di tali flags.

Le etichette sono essenziali per le istruzioni di salto in quanto indicano a quale punto della sequenza di istruzioni bisogna saltare. Occorre inserire prima dell’istruzione a cui si vuole saltare un nome simbolico seguito dal carattere “:”.

In Assembly non esistono istruzioni ad alto livello per realizzare i cicli come FOR …, WHILE …; essi si devono costruire manualmente a partire dalle istruzioni di salto condizionato. Se si vuole eseguire un ciclo per un certo numero di volte occorre utilizzare ECX come contatore.

Le funzioni

Una funzione in assembly si definisce mediante il seguente costrutto:

nome_funzione: .type @function
istruzione 1
istruzione 2
....
....
istruzione n
ret

La funzione può essere richiamata utilizzando l’istruzione call nome_funzione. Gli eventuali parametri della funzione devono essere caricati nei registri della CPU o nello stack. All’interno del corpo della funzione i parametri possono essere recuperati accedendo ai registri o allo stack impostati prima della chiamata alla funzione.

Biografia

Sono uno specialista in materia di sicurezza informatica, scrittore, contributore per il progetto Monero, una criptovaluta che è focalizzata nel proteggere le informazioni sulle transazioni. Il libro che ho pubblicato Mastering Monero è diventato una delle migliori risorse per padroneggiare Monero. Più informazioni su di me

Seguimi su Twitter o scrivimi una e-mail. Le donazioni sono molto apprezzate, mi permettono di continuare a lavorare e a scrivere.

Mastering Monero Book