Linguaggio macchina in Pascal (BASM).


Sommario
REGISTRI CPU 8086:


AX
BX
CX
DX

CS
DS
ES
SS

SP
BP
SI
DI

Accumulatore, scomponibile in AH e AL
Scomponibile in BH e BL
Contatore, scomponibile in CH e CL
Scomponibile in DH e DL

Segmento codice. 
Segmento dati. 
Segmento extra. 
Segmento stack. 

Stack pointer. 
Base pointer (punta all'interno dello stack). 
Registro sorgente 16 bit. 
Registro destinazione 16 bit.


AVVERTENZE:

Un blocco assembler deve preservare i registri BP SP SS e DS, e può modificare liberamente AX BX CX DX SI DI ES e il registro dei flag

In una procedura o funzione assembler lo stack è quello della funzione o procedura in cui il blocco è presente, BP punta al frame corrente nello stack, SP punta alla cima dello stack, SS contiene l'indirizzo del segmento dello stack e DS l'indirizzo del segmento dati. 

Possono essere usate solo le direttive DB DW e DD

Le label devono essere precedute dal simbolo @ (es: JMP @INIZIO) e sono dette label locali in quanto visibili solo nel blocco assembler. 

Se servono variabili nel modulo assembler queste vanno definite nella sezione VAR e vi si può accedere poi direttamente specificandone il nome: 

function z(const str:string):string;
var
  tot1,tot2:byte;
  tot3:word;
begin
  asm
    MOV AL,tot1
    MOV BH,tot2
    MOV CX,tot3
La direttiva EQU viene sostituita con una dichiarazione CONST: 
function z(const str:string):string;
const
  valore=120;
begin
  asm
    MOV AL,valore

PASSAGGIO PARAMETRI:

Un parametro passato per indirizzo (VAR o CONST) può essere trovato con le istruzioni LES o LDS che caricano in una coppia di registri il suo indirizzo effettivo: 

function delspace(const str:string):string;
begin
  asm
    PUSH DS
    LDS SI,str  (* DS:SI=indirizzo str *)
    LDS DI,str  (* DS:DI=indirizzo str *)
    LES SI,str  (* ES:SI=indirizzo str *)
    LES DI,str  (* ES:DI=indirizzo str *)
Un parametro passato per valore può essere caricato direttamente in un registro, dati char, boolean, byte e shortint vanno caricati in un registro a 8 bit, integer e word in un registro a 16 bit, longint in una coppia di registri a 16 bit: 
function XYZ(n:byte;g:word;k:longint):string;
begin
  asm
    MOV CL,n
    MOV DX,g
    MOV AX,WORD[k]    (* AX=parte alta  di k *)
    MOV BX,WORD[k+2]  (* BX=parte bassa di k *)
Se il risultato di una funzione (valore di ritorno) è una stringa il suo indirizzo si può trovare con: 
          LES DI,@Result  (* ES:DI=indirizzo risultato *)
    LES SI,@Result  (* ES:SI=indirizzo risultato *)
    LDS DI,@Result  (* DS:DI=indirizzo risultato *)
    LDS SI,@Result  (* DS:SI=indirizzo risultato *)

SALTI:

JMP @label è il salto incondizionato. 

Tutti i salti condizionali sono a 8 bit, saltano cioè al massimo a ±127 byte. 

B=minore    A=maggiore    E=uguale    N=non 
 
JE (JZ) = Uguale
JNE (JNZ) <> Diverso
JB (JC) < Minore
JA > Maggiore
JBE <= Minore o uguale
JAE (JNC) >= Maggiore o uguale

Esistono anche le forme JNB (non minore cioè maggiore o uguale), JNA (non maggiore cioè minore o uguale), JNBE (non minore o uguale cioè maggiore), JNAE (non maggiore o uguale cioè minore). 

Il salto condizionale JCXZ @label consente di saltare se il contenuto del registro CX vale zero.


CICLI:

LOOP @label effettua CX iterazioni, se CX vale 0 effettua 65536 cicli. 

LOOPE e LOOPNE Effettuano CX iterazioni oppure si arrestano se il flag di zero è settato (E) o resettato (NE). 

LOOPZ e LOOPNZ sono identiche rispettivamente a LOOPE e LOOPNE.


ISTRUZIONI DI STRINGA:

Le istruzioni di stringa vengono controllate dal flag di direzione, se il flag è a 0 (CLD) la direzione è l'incremento, se il flag è a 1 (STD) la direzione è il decremento: 

LODSB   DS:[SI]  --->  AL         SI ± 1
LODSW   DS:[SI]  --->  AX         SI ± 2

STOSB   AL  -------->  ES:[DI]    DI ± 1
STOSW   AX  -------->  ES:[DI]    DI ± 2

MOVSB   DS:[SI]  --->  ES:[DI]    SI ± 1    DI ± 1
MOVSW   DS:[SI]  --->  ES:[DI]    SI ± 2    DI ± 2
SCASB confronta AL con il valore in ES:[DI] impostando i flag come con una operazione CMP, poi incrementa (o decrementa) DI a seconda del valore del flag di direzione (i flag non sono alterati dall'inc/dec ma solo dal cmp). 

SCASW è la versione a 16 bit, confronta AX con ES:[DI] e incrementa o decrementa DI di 2 anzichè di 1. 

CMPSB confronta due byte presenti in DS:[SI] e ES:[DI], poi incrementa o decrementa SI e DI di 1. 

CMPSW confronta due word presenti in DS:[SI] e ES:[DI], poi incrementa o decrementa SI e DI di 2. 

Il prefisso REP consente di eseguire una delle precedenti istruzioni CX volte, se CX vale 0 l'istruzione non viene eseguita neppure una volta, quindi al max è possibile ripeterla 65535 volte. 

    MOV CX,100
    REP MOVSB
I prefissi REPE o REPNE (e gli equivalenti REPZ e REPNZ) sono applicabili alle istruzioni SCAS_ e CMPS_ e consentono di tenere conto del risultato di un CMP implicito che imposta il flag di zero. 


Pagina realizzata da Claudio Fin
Ultimo aggiornamento 22-9-2000