PROGRAMMAZIONE ASSEMBLY #10 : ISTRUZIONI ARITMETICHE


Le istruzioni logico – aritmetiche sono istruzioni eseguite dalla ALU, Il risultato di un’istruzione L/A modifica lo stato del registro dei flag e richiedono sempre uno o due operandi.
􀀁
􀀁Classi di istruzioni:

  • Somma, Sottrazione, Negazione
  • Moltiplicazione, Divisione
  • 􀀁Operazioni logiche (AND, OR, XOR, NOT)
  • 􀀁Incremento e decremento􀀁
  • Shift e rotazione
  • Confronto e test

IL REGISTRO DEI FLAG

Il registro dei flag è composto da 16 bit, ognuno dei quali può assumere valore 1 or 0

􀀁Carry Flag (CF)
􀀂Il flag è impostato a 1 quando il risultato di un’operazione genera un overflow senza segno
􀀁Zero Flag (ZF)
􀀂Il flag è impostato a 1 quando il risultato di un’operazione è pari a zero
􀀁Sign Flag (SF)
􀀂Il flag è impostato a 1 quando il risultato di un’operazione è negativo
􀀁Overflow Flag (OF)
􀀂Il flag è impostato a 1 quando il risultato di un’operazione genera un overflow con segno
􀀁Parity Flag (PF)
􀀂Il flag è impostato a 1 quando nel risultato di un’operazione c’è un numero pari di 1

OPERAZIONI ARITMETICHE

Le istruzioni aritmetiche vengono raggruppate in base alle 4 operazioni aritmetiche fondamentali:

ADDIZIONE:

  • ADD = Addizione
  • ADC = Addizione con riporto
  • INC  = Incremento
  • NEG = Negazione

SOTTRAZIONE

  • SUB = Sottrazione
  • SBB = Sottrazione con riporto
  • CMP = Confronto tra due valori
  • DEC = Decremento

MOLTIPLICAZIONE

  • MUL = Moltiplicazione senza segno
  • IMUL = Moltiplicazione con segno

DIVISIONE

  • DIV = Divisione senza segno
  • IDIV = Divisione con segno

OPERAZIONI DI SOMMA E DIFFERENZA

Le operazioni di somma e differenza vengono eseguite tramite le istruzioni ADD, ADC, SUB, SBB, CMP
􀀁La sintassi di queste istruzioni è uguale per tutte:
􀀁<istruzione> <op1>, <op2>
􀀁<op1> e <op2> possono essere registri, valori immediati o indirizzi di memoria.
􀀁Al termine dell’operazione, il risultato è sempre memorizzato nel primo operando (tranne che per l’istruzione CMP), ma non tutte le combinazioni di operandi sono lecite, infatti:
􀀁Un valore immediato non può essere primo operando e 􀀁 sono inoltre vietate somme/differenze tra indirizzi di memoria.

OPERAZIONI DI SOMMA

L’operazione di somma può essere eseguita tramite l’istruzione ADD.
􀀁La sua sintassi è la seguente:

ADD <op1>, <op2>
L’istruzione ADD addiziona al primo operando (che rappresenta la destinazione del risultato) il secondo operando
􀀁Esempio:
MOV AL, 2                ; AL = 2
􀀁MOV AH, -7              ; AH = -7
􀀁ADD AL, AH              ;AL = -5
􀀁RET
􀀁L’operazione di somma può essere eseguita tramite l’istruzione ADC (ADdition with Carry)
La sua sintassi è uguale all’ istruzione ADD.
􀀁ADC addiziona al primo operando (che rappresenta la destinazione del risultato) il secondo operando e il valore del bit di CF (carry flag).

OPERAZIONI DI DIFFERENZA

L’operazione di differenza viene eseguita tramite l’istruzione SUB
􀀁Sintassi: SUB <op1>, <op2>
L’istruzione SUB sottrae dal primo operando (che rappresenta la destinazione del risultato) il secondo operando.
􀀁Esempio:
􀀁MOV AX, 10      ; AX = 10
􀀁SUB AX, 1          ; AX = 9
􀀁RET

􀀁L’operazione di differenza può essere eseguita tramite l’istruzione SBB
􀀁Sintassi: SBB <op1>, <op2>
L’istruzione SBB sottrae dal primo operando (che rappresenta la destinazione del risultato) il secondo operando e il valore del bit di CF (carry flag).

L’operazione di differenza può essere eseguita anche tramite l’istruzione CMP, al solo fine di effettuare un confronto fra gli operandi.
􀀁Sintassi: CMP <op1>, <op2>
􀀁L’istruzione CMP sottrae dal primo operando il secondo operando, modificando solo i bit di flag.
􀀁Il risultato della sottrazione eseguita da CMP non viene memorizzato e􀀁 i flag assumono valore 0 o 1 in base al risultato della sottrazione.
􀀁Esempio:
􀀁MOV AX, 12
􀀁MOV BX, 5
􀀁CMP AX, BX                       ;ZF(zero flag) = 0 (AX e BX sono diversi!)

OPERAZIONI DI INCREMENTO E DECREMENTO

Le operazioni di incremento e decremento (somma e differenza di 1) vengono eseguite tramite le istruzioni

INC, DEC
􀀁La sintassi di queste istruzioni è analoga per entrambe:
􀀁<istruzione> <op1>
􀀁<op1> può essere:

  • Un registro;
  • Un indirizzo di memoria.

􀀁Al termine dell’operazione, l’operando risulta incrementato o decrementato di 1

L’ ISTRUZIONE NEG

Il linguaggio Assembly mette a disposizione un’ istruzione particolare di nome NEG. La si usa per calcolare il negativo di un numero, il quale viene espresso in COMPLEMENTO A 2.
􀀁Sintassi: NEG <op1>
􀀁 <op1> può essere:

  • Un registro;
  • Un indirizzo di memoria.

L’istruzione NEG altro non fa che Invertire tutti i bit dell’operando ed􀀂 aggiunge 1 all’ operando invertito.

OPERAZIONI DI PRODOTTO E DIVISIONE

Le operazioni di prodotto e divisione vengono eseguite tramite le istruzioni MUL, IMUL, DIV, IDIV e 􀀁la sintassi di queste istruzioni è analoga per tutte:
􀀁<istruzione> <op1>
􀀁<op1> può essere:

  • Un registro;
  • Un indirizzo di memoria.

􀀁Le istruzioni MUL, IMUL, DIV, IDIV utilizzano i registri AX e DX; inoltre􀀁 le istruzioni MUL, IMUL influenzano solo i flag CF (carry) e OF (overflow), mentre 􀀁le istruzioni DIV, IDIV lasciano i flag indefiniti.

OPERAZIONI DI PRODOTTO

Con la sintassi dell’istruzione viene specificato solo un fattore della moltiplicazione (<op1>).
􀀁Il secondo fattore viene assunto di default tramite il registro AX
N.B. 􀀁Entrambi gli operandi devono avere la stessa grandezza (byte o word).􀀁 Il risultato del prodotto è memorizzato in uno spazio di lunghezza doppia rispetto a quella dei fattori.
􀀁Caso 1: byte × byte
􀀁se <op1> è pari a 1 byte, lo stesso viene moltiplicato per il contenuto di AL e il risultato è memorizzato in AX
􀀁Caso 2: word × word
􀀁se <op1> è pari a 1 word, lo stesso viene moltiplicato per il contenuto di AX e il
risultato è memorizzato in [DX : AX], ciò vuol dire che􀀂 DX contiene la word più significativa, AX la word meno significativa.

OPERAZIONI DI DIVISIONE

Con la sintassi dell’istruzione viene specificato solo il secondo fattore (divisore) della divisione (<op1>).
􀀁Il primo fattore (dividendo) viene assunto tramite i registri AX e DX.
N.B. Il dividendo occupa uno spazio doppio rispetto al fattore specificato (divisore)
􀀁Il risultato della divisione è duplice: quoziente e resto:
􀀁Quoziente e resto sono memorizzati in uno spazio di lunghezza pari alla metà rispetto a quella del dividendo (ossia pari a quella del fattore specificato)

􀀁Caso 1: Divisore (<op1>) lungo 1 byte
􀀁Il contenuto di AX (dividendo) viene diviso per <op1> (divisore), il quoziente è memorizzato in AL e il resto è memorizzato in AH.

􀀁Caso 2: Divisore (<op1>) lungo 1 word
􀀁il contenuto di [DX : AX] (dividendo) viene diviso per <op1> (divisore), il quoziente è memorizzato in AX e il resto è memorizzato in DX
􀀂Quindi DX contiene la word più significativa del dividendo, AX la word meno significativa.

Pubblicato il 6 agosto 2015, in PROGRAMMAZIONE ASSEMBLY con tag , , , , , , , , . Aggiungi il permalink ai segnalibri. Lascia un commento.

Lascia un commento