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
|