| Di solito la direttiva SEGMENT
viene seguita da una serie di opzioni di 3 tipi
diversi: l'allineamento
(aling), il rango (combine)
e la classe ('class').
Nell'esempio viene presentata la direttiva SEGMENT con le scelte usate in
questo tutorial:
_prog
SEGMENT BYTE PUBLIC 'CODE'
; qui vanno inserite le istruzioni
_prog ENDS |
|
| L'opzione di classe
va sempre indicata tra apici e può servire per differenziare con nomi
diversi i bytes appartenenti a segmenti dello stesso rango. |
| Le opzioni di rango
indicano all'assemblatore il modo di manipolare (combinare,
(combine)) i segmenti della stessa
classe (cioè con lo stesso nome); se non viene specificato alcun rango
(opzione di default) ciascun segmento sarà separato agli altri e verrà
allocato in memoria nella posizione indicata dal proprio indirizzo fisico,
anche in posizioni non adiacenti. Il rango può essere PUBLIC,
STACK, COMMON,
MEMORY e AT.
Vediamoli in dettaglio:
| PUBLIC:
se i segmenti della stessa classe (per esempio tutti quelli di nome 'Code')
hanno questo rango l'assemblatore provvede a lasciare indicazioni
affinché il
linker
possa riunirli in un unico blocco contiguo,
ponendoli uno dopo l'altro a partire dalla locazione iniziale suggerita
dall'opzione di allineamento. Questo comporta la rilocazione degli
indirizzi di alcuni blocchi concorrenti, in modo da essere comunque
relativi all'inizio del nuovo
segmento. |
| STACK:
come per il rango PUBLIC
l'assemblatore provvede a lasciare indicazioni affinché il
linker
possa riunire in un unico blocco contiguo
tutti i segmenti della stessa classe (per esempio tutti quelli di nome
'Stack')
con questo rango; questa volta però il nuovo segmento, frutto del
concatenamento di tutti gli altri, sarà automaticamente assegnato al
registro di segmento SS,
mentre il registro SP sarà
fatto puntare alla sua fine. Se non
specifichiamo il rango STACK
per il nostro segmento di stack (ammesso che vogliamo definirlo) dovremo
provvedere noi (con istruzioni esplicite nel programma sorgente) ad
assegnarlo al registro SS. |
|
In
alternativa, la direttiva .STACK può servire per
obbligare l'assemblatore a generare uno stack di 1024 bytes;
specificando un numero dopo di essa è anche possibile modificare la
dimensione di default (es: .STACK 64 crea uno stack di 64
bytes). |
| COMMON:
l'assemblatore lascia indicazioni affinché il
linker
sovrapponga i segmenti della stessa
classe con questo rango; questo comporta il fatto che i riferimenti a
etichette presenti in più segmenti vengano in effetti fatti a quella
caricata per ultima. |
| MEMORY: il
linker
della Microsoft non supporta questo rango, per cui i segmenti di questo
tipo saranno trattati come fossero PUBLIC; in realtà dovrebbero invece
essere allocati nell'ultimo segmento disponibile in memoria, cioè
quello associato agli indirizzi più alti, comunque dopo tutti gli altri
segmenti allocati. |
| AT:
questo rango consente di localizzare un'area di memoria a partire da un ben preciso indirizzo fisico di
segmento specificato subito dopo AT. |
|
Questa
direttiva è decisamente interessante e può tornar utile in casi
particolari; con essa è possibile coprire e gestire
facilmente tutti i dati contenuti in una particolare area
di sistema, di solito di dimensione inferiore al segmento
(64k), come la Tabella dei Vettori
(a partire da
0000:0000) o l'Area
di Comunicazione Bios (0000:0400H), o la
Ram Video
nei modi testo (B800:0000)
e così via... |
|
|
La sintassi è leggermente diversa da quella
degli altri ranghi, non essendo necessario definire ne allineamento ne
classe: tutte le etichette
specificate dentro questo particolare segmento saranno relative
all'indirizzo di segmento assoluto specificato,
a partire dall'indirizzo di offset
0000
(se non diversamente specificato dalla eventuale direttiva ORG). Data la
sua particolarità forniamo 2 esempi di applicazione, da inserire a
piacere nel nostro codice sorgente:
TABint
SEGMENT AT 0000H
ORG 0009H*4 ; Localizza l'indirizzo del puntatore
INT_09 LABEL DWORD ; alla locazione di servizio
dell'INT 09H
TABint ENDS
ASSUME ES:TABint |
areaBIO
SEGMENT AT 0040H
ORG 0001AH ; Localizza l'indirizzo dell'area di co-
; municazione BIOS dedicata alla tastiera
inizioBuff DW ? ;
inizioBuff = inizio BUFFER
fineBuff DW ? ; fineBuff = fine del BUFFER
Buffer DW 16 DUP(?); Buffer =
vera area per i codici tasti
postBuff LABEL word ; postBuff = locazione successiva
all'ul-
areaBIO ENDS ; tima
del BUFFER
ASSUME ES:areaBIO |
|
|
Si
osservi come, in entrambi gli esempi si sia deciso di puntare i 2
segmenti con il registro ES poiché esso è il puntatore alla zona ExtraDati
è sempre una buona scelta. In questo modo l'assemblatore compilerà il
codice che punta ciascuna delle etichette interne con override
ES: (MOV
AL,ES:[INT_09])
mentre è necessario evitare di scrivere senza override le istruzioni di
puntamento tramite registro (come MOV
AL,[SI]) per evitare la compilazione
di default con riferimento a DS (cioè bisogna scrivere
MOV
AL,ES:[SI]). |