Operazioni di trasferimento e operazioni aritmetiche
In un programma il numero 1000 potrebbe rappresentare il valore 1000 in base 10 oppure il valore 8 espresso in binario. Per evitare l'ambiguità, dopo le cifre che lo rappresentano, un operando numerico è seguito da un simbolo che specifica la base in cui è espresso quel numero:
Simbolobase
bBinario
oOttale
hEsadecimale
Nota: per indicare la base Ottale si usa la lettera o minuscola per non confonderla con lo zero.

Nota: un numero deve sempre iniziare con una cifra. Infatti in un programma la lettera A potrebbe essere l'identificatore di una variabile. Per indicare che si tratta del numero esadecimale si deve scrivere 0Ah.
  1. Avviare emu8086
  2. Nel menu "File" selezionare il comando "Samples" e scegliere l'esempio numero 1.


    1. Click sul pulsante [Compile and Emulate] (o premere il tasto F5).
    Si apre una nuova finestra

    1. Click sul pulsante [Single Step] (o premere il tasto F8)
    ad ogni presione del pulsante [Single Step] osservare i valori contenuti nei registri.

Numeri con segno


La rappresentazione di un numero nella memoria è comunque formata da una serie di cifre binarie, ma la sua interpretazione è affidata al programmatore. Ad esempio il numero 0FFh rappresenta sia il numero decimale 255 senza segno che il numero negativo -1. Quale sia il valore da considerare è una decisione che spetta al programmatore.

Con 8 bit si possono formare 256 combinazioni. Se si vogliono rappresentare numeri con segno allora le prime 128 combinazioni rappresentano i numeri positivi da 0 a 127 e le ultime 128 configurazioni (da 128 a 255) rappresentano i numeri negativi.

Quale dovrebbe essere la codifica di -5? Sottraendo 5 da 256 si ottiene 251, la codifica di -5. Infatti la somma di -5 con 5 deve dare 0, come accade sommando 5 con 251 avendo a disposizione 8 bit.

Il segno del numero viene individuato dal valore del bit più a sinistra: Infatti i numeri da 128 a 255 hannoil bit 7 a livello 1.

Lo stesso metodo viene applicato ai numeri rappresentati in una word: i positivi sono compresi tra 0 e 32767 e i negativi da 32768 a 65535.

Calcoli con l'emulatore
L'emulatore dispone di due utili strumenti: un convertitore del codice di numeri e una calcolatrice.

Number Convertor consente di convertire un numero. Basta scrive il numero in una qualsiasi casella di testo e automaticamente viene mostrato il codice negli altri sistemi di numerazione.

Expression Evaluator consente di fare calcoli tra numeri espressi in diversi sistemi di numerazione e converte il risultato. Basta Scrivere un'espressione e premere Invio, Il risultato appare nel sistema di numerazione scelto.

Per esempio, per calcolare: 0FFFFh * 10h + 0FFFFh (massima locazione si memoria indirizzabile dalla CPU 8086). Se si spuntano le caselle Signed e Word si ottiene il risultato. -17 (perchè: (-1) * 16 + (-1). Lo stesso calcolo ripetuto togliendo la marca di spunta a lla casella Signed il risultato è: 65535 * 16 + 65535 cioè 1114095.

Le operazioni ammesse sono:
~       not (inverts all bits).
*       multiply.
/       divide.
%       modulus.
+       sum.
-       subtract (and unary -).
<<      shift left.
>>      shift right.
&       bitwise AND.
^       bitwise XOR.
|       bitwise OR.



Esempi
#make_BIN#
; scopo del programma
; calcola la somma degli elementi dell'array V1
; scrive il risultato in V2.

; numero di elementi dell'array V1:
MOV CX, 5 

; il registro AL conterrà la somma:
MOV AL, 0

; il registro BX viene usato come indice dell'array:
MOV BX, 0

; inizia la somma degli elementi:
ripeti: ADD AL, V1[BX]

; l'elemento dell'array viene sostituito con il suo indice
MOV V1[BX], BL

; passa al successivo elemento:
INC BX

; se CX>0 continua l'esecuzione dall'istruzione 
; identificata con ripeti:
LOOP ripeti

; memorizza il risultato in v2:
MOV V2, AL

HLT

; variabili:
V1 DB 4, 3, 2, 1, 0
V2 DB 0

In questo esempio si illustra l'effetto dell'istruzione CMP (compare) sulle flag.

A seconda dell'esito del confronto il programma può subire una diramazione mediante un'istruzione jump (salto): JE (Jump if Equal), JA (Jump if Above), ...

L'istruzione NOP significa no operation.

Nel menu View aprire il "Lexical Flag Analyzer" e la finestra "Flags" prima di eseguire questo programma passo passo.

Gli esempi che seguono eseguono il confronto tra numeri con segno e senza segno. Dopo ogni confronto osservare le flag modificate.
#make_BIN#

; 4 è uguale a 4
MOV AH, 4
MOV AL, 4
CMP AH, AL
NOP

; 4 è superiore o maggiore di 3
MOV AH, 4
MOV AL, 3
CMP AH, AL
NOP

; numero con segno
; -5 = 251 = 0FBh
; 1 is Greater then -5
MOV AH, 1
MOV AL, -5
CMP AH, AL
NOP

; Numero senza segno
; 1 è inferiore a 251
MOV AH, 1
MOV AL, 251
CMP AH, AL
NOP

; Numeri con segno
; -3 è minore di -2
MOV AH, -3
MOV AL, -2
CMP AH, AL
NOP

; Numeri con segno
; -2 è maggiore di -3
MOV AH, -2
MOV AL, -3
CMP AH, AL
NOP

; Numeri senza segno
; 255 è superiore a 1
MOV AH, 255
MOV AL, 1
CMP AH, AL
NOP

HLT


AAA: ASCII Adjust after Addition
Questo esempio illustra l'uso dell'istruzione AAA. Questa istruzione viene richiamata dopo un'addizione per ottenere le cifre BCD del numero esadecimale maggiore di 9.
#make_COM#

ORG     100h

; Il primo addendo è '9':
MOV     AH, 09h

; Il secondo addendo è '5':
MOV     AL, 05h

; AL = AL + AH =
;    = 09h + 05h = 0Eh
; Il risultato non è una cifra BCD:
ADD     AL, AH

; Azzera il byte che deve contenere la cifra delle decine
XOR     AH, AH

; Riporta il risultato in BCD,
; AH = 1, AL = 4  ->  '14'
AAA

; Per stampare il risultato
; il contenuto del registro AX viene copiato in DX
; perchè in AX devono essere inseriti i parametri
; della chiamata di funzione:
MOV     DX, AX

; per richiedere la stampa
; 1) AH deve contenere il codice 0Eh (stampa un carattere)
MOV     AH, 0Eh

; 2) AL deve contenere il codice ASCII del carattere da stampare
OR      DH, 30h
MOV     AL, DH

; 3) richiamare il servizio INT 10:
INT     10h

; Stampa della seconda cifra:
; conversione in ascii:
OR      DL, 30h
MOV     AL, DL
INT     10h
RET
END

Somma
In questo esempio si mostra come sommare numeri BCD
#make_COM#
ORG     100h

; Salta la dichiarazione delle variabili:
JMP     start

; numero di cifre da elaborare:
len     EQU     5

; il primo numero è: '79,521'
num1    DB      1,2,5,9,7

; il secondo numero è: '82,191':
num2    DB      1,9,1,2,8

; la voariabile contenente il risultato, '161.712':
sum     DB      6 DUP (0)

start:  ; Inizio codice.

; Puntatore alle cifre dei numeri:
XOR     BX, BX

; contatore del ciclo:
MOV     CX, len 
        
CifraSucc

        ; Somma le cifre:
        MOV     AL, num1[BX]
        ADC     AL, num2[BX]
        
        ; ASCII adjust:
        AAA
        
        ; Memorizza il risultato:
        MOV     sum[BX], AL
        
        ; punta alla prossima cifra:
        INC     BX
        
        LOOP    CifraSucc

; aggiungi anche il riporto:
ADC     sum[BX], 0


; stampa il risultato:
MOV     CX, len+1

; La stampa inizia dalla cifra meno significativa:
MOV     BX, len

stampaCifra:
        MOV     AL, sum[BX]
        ; converti in carattere ASCII:
        OR      AL, 30h

        MOV     AH, 0Eh
        INT     10h
        
        DEC     BX
        
        LOOP    stampaCifra

RET

END


Sottrazione
Questo esempio illustra l'istruzione AAS, usata per la sottrazione di numeri BCD.
#make_COM#
ORG	100h
; Sottrazione da eseguire: 5 - 9. Il risultato AL = 0FCh non è BCD
MOV	AL, 05h
MOV	BL, 09h
SUB	AL, BL

; converte in BCD, AL = 6 
; 1 viene preso in prestito da AH, corrisponde a calcolare 15 - 9:
AAS

; converte in codice ASCII:
OR	AL, 30h

; stampa del carattere contenuto in AL usando una funzione del BIOS:
MOV	AH, 0Eh
INT	10h
RET
END

Operazioni sulle stringhe
Questo esempio illustra l'uso dell'istruzione CMPSB (Compare String Byte)
#make_COM#
        ORG     100h
; imposta la flag di direzione (indirizzi crescenti):
        CLD     

; puntatore alla prima stringa DS:SI,
; puntatore alla seconda stringa ES:DI:
        MOV     AX, CS
        MOV     DS, AX
        MOV     ES, AX
        LEA     si, str1
        LEA     di, str2

; contatore inizializzato con lunghezza della stringa:
        MOV     CX, 11

; ripeti il confronto fintanto che sono uguali:
        REPE    CMPSB
        JNZ     diverse

; "Sė" - uguaglianza
        MOV     AL, 'S'
        MOV     AH, 0Eh
        INT     10h

        JMP     esci

diverse:

; "No" - stringhe diverse
        MOV     AL, 'N'
        MOV     AH, 0Eh
        INT     10h

esci:

        RET

; data:
str1 db 'stringa di prova'
str2 db 'stringa di prova'
END