Quasi sempre il linguaggio di programmazione mnemonico o linguaggio macchina o assembly costituisce un punto di arrivo, non necessariamente obbligato, per il programmatore evoluto. Questo paradossalmente potrebbe costituire un ostacolo ad un primo approccio alla programmazione in mnemonico, in quanto si è ormai abituati alla disponibilità di tutto un insieme di strutture, tipiche dei linguaggi evoluti, che consentono all'utente di dedicare la gran parte delle proprie energie, com'è giusto che sia, alla soluzione del problema senza la necessità di sapere come in effetti il processore e le strutture ad esso collegate risolvano molti dei passaggi intermedi.

          Generalmente, dato un problema, se ne ricava la soluzione per scomposizioni successive in sottoproblemi fino a quando ciascuno di questi sottoproblemi non costituisca di fatto una delle strutture di base del linguaggio utilizzato per rappresentare la soluzione stessa. Il passaggio da un linguaggio evoluto ad uno mnemonico comporta, in primo luogo, una ulteriore scomposizione dei sottoproblemi, in quanto le strutture di base offerte dal linguaggio assembly sono più elementari. Dovendo, ad esempio, emettere un messaggio sul video (dispositivo di uscita standard in modalità testo) con un linguaggio evoluto si risolve il problema scrivendo semplicemente una frase del tipo:

Write ('Messaggio')

con un linguaggio assembly il problema può essere risolto o conoscendo i dettagli costruttivi della macchina o collegandosi con qualcuno dei sottoprogrammi, appartenenti al Sistema Operativo oppure alla dotazione di base della macchina (BIOS), che risolvono il problema; in ogni caso si va incontro ad almeno due tipi di inconvenienti:           Ma allora, perchè programmare in linguaggio macchina? La risposta dipende, anche, dal punto di vista del programmatore, ecco alcuni motivi che possono essere plausibili:           Come si vede, non mancano le motivazioni per utilizzare, anche se in modo parziale, il linguaggio assembly nei propri programmi, infatti dall'analisi dei punti precedenti emerge certamente una costante: esistono classi di operazioni che vengono gestite in modo poco efficiente dai linguaggi evoluti, l'assembly colma queste carenze. Esiste comunque un quarto motivo per avvicinarsi all'assembly che prescinde da considerazioni utilitaristiche:           In conclusione vogliamo ricordare che lavorare in linguaggio assembly significa scomporre il problema originario in sottoproblemi più elementari rispetto a quanto non si faccia con un linguaggio evoluto. Tipicamente, in assembly, le elaborazioni di base consistono in: ed è soltanto tramite queste semplici funzioni che si può confezionare l'algoritmo risolutivo di un particolare problema; e sono ancora soltanto queste semplici funzioni che consentono di creare le strutture più complesse disponibili con i linguaggi evoluti.

La modalitÓ reale era l'unica possibilitÓ per usare la memoria in dotazione al processore 8086, il progenitore dei vari 80386, 80486, Pentium, tutti a 32-bit. L'8086, benchŔ fosse una CPU a 16-bit, prevedeva un ingegnoso e semplice meccanismo per accedere fino ad un massimo di 1MB di memoria fisica (reale). Tale modalitÓ di indirizzamento, chiamata reale, utilizza una combinazione di due registri (Segment:Offset) a 16-bit per formare un indirizzo a 20-bit che consente l'accesso a tutti i byte del primo e unico Mb di memoria (istruzioni o dati). Ciascuna istruzione usa uno dei quattro registri di segmento disponibili (CS, DS, ES, SS), sia implicitamente sia esplicitamente.

figura 1

Il calcolo dell'indirizzo avviene traslando, a sinistra di quattro posti, i bit del registro di segmento (moltiplicazione x 16) e sommandogli uno dei nove registri generali, tipicamente quello specificato nell'istruzione.
Il risultato sarÓ un indirizzo a 20-bit (da 0 a 19) che consentirÓ di indirizzare uno spazio di 1 Mb usando registri a 16-bit. L'eventuale bit n. 20, di riporto, verrÓ perso.

Fermo restando il registro di segmento, al variare del registro di offset sarÓ possibile indirizzare soltanto 64 Kb di memoria, pertanto per accedere ad una quantitÓ maggiore di memoria Ŕ necessario utilizzare pi¨ di un registro di segmento. Sicuramente chi ha sviluppato applicazioni Intel avrÓ sentito parlare di vari modelli di memoria utilizzati fino a non molto tempo fa: tiny, small, medium, compact, large, huge. Questi modelli propongono varie combinazioni di segmenti per superare la limitazione imposta dai registri a 16-bit al fine di potere utilizzare dati e codice pi¨ grandi di 64 Kb.

Per abbattere inoltre la limitazione di 1 Mb, sono stati introdotti altri accorgimenti complicati come la memoria espansa e la memoria estesa. Questi software di gestione della memoria hanno da una parte aiutato a superare il problema, ma dall'altra hanno introdotto un aumento della complessitÓ della gestione della memoria con conseguente sovraccarico di lavoro.

I compilatori, i linker ed i loader di sistema operativo si prendono carico di assegnare gli opportuni valori ai registri di segmento per togliere agli sviluppatori di applicazioni ogni responsabilitÓ in merito. I programmatori di sistema, che lavorano prevalentemente in assembly, non sono cosý fortunati e incappano nella complessitÓ di questi schemi. L'origine di tutti questi problemi nasce dalla limitazione dei registri a 16-bit che possono specificare fino ad un massimo di 64 K indirizzi diversi, mentre sarebbero necessari 20-bit per raggiungere 1 Mb, 24-bit per i 16 Mb, o ancora di pi¨ per quantitÓ di memoria superiori.

Nel 1986, con l'avvento del microprocessore Intel 80386, le cose cominciarono a cambiare radicalmente. Quel processore era veramente un processore a 32-bit. I maggiori vantaggi della programmazione a 32-bit, rispetto a quella a 16-bit o ad 8-bit, si possono sintetizzare in due parole: semplicitÓ e velocitÓ. Le stesse istruzioni divennero pi¨ veloci sia per l'aumento del clock sia per la maggiore efficienza; una singola istruzione (aritmetica, logica, di gestione memoria o stringhe) pu˛ operare su 32 bit al posto di due istruzioni a 16 bit o quattro a 8 bit. Con la riduzione del numero delle istruzioni si riducono le dimensioni del programma ed aumenta la velocitÓ di esecuzione, poichŔ si riducono i tempi delle due fasi di fetch ed execute. Minori dimensioni degli eseguibili e maggiore velocitÓ sono sempre stati obiettivi importanti per gli informatici.

Ma la cosa pi¨ innovativa fu che l'unitÓ di gestione della memoria (MMU) di questa CPU introdusse una nuova modalitÓ di indirizzamento, oltre quella reale, chiamata modalitÓ protetta. Questa modalitÓ offre un altissimo grado di flessibilitÓ consentendo l'indirizzamento, per ogni applicazione attiva, di una vastissima area di memoria (4 Gb) non segmentata o piatta (flat) e quindi con l'uso dei soli registri di offset. Non solo, ma questi 4 Gb posono essere utilizzati all'interno di una memoria virtuale estesa fino a ben 64 Tb (Terabyte = 1012).
Questa modalitÓ consente, inoltre, la protezione per consentire il funzionamento di tutti i software che ne hanno di bisogno, come i sistemi Unix o compatibili.

Nella modalitÓ protetta, gli ex registri di segmento vengono chiamati selettori e fungono da indici di speciali tabelle, inizializzate e mantenute dal sistema operativo, ma interpretate direttamente dalla CPU. Esistono tre tipi di queste speciali tabelle, tutte residenti nella RAM o nella ROM:

Ogni tabella pu˛ contenere un numero variabile di descrittori, ciascuno con una struttura di 8-byte per poter descrivere gli estremi di una data regione di memoria ed i suoi attributi:

figura 2

Gli ex registri di segmento sono adesso divenuti registri selettori (indici) e servono per indicare il particolare descrittore all'interno della GDT o della LDT (i descrittori contenuti nella IDT entrano in gioco solo per la gestione delle interruzioni). Un selettore (uno dei 6 registri di segmento: CS, DS, ES, FS, GS, SS) contiene un valore indice a 13-bit, un bit per identificare la tabella da usare (GDT/LDT), e 2-bit per specificare il livello di protezione.

figura 3



          Prova anche questi: In questa sezione vengono proposte semplici applicazioni in linguaggio macchina a 16 bit, sviluppate sotto forma di funzioni richiamabili da Pascal. Gli strumenti necessari per la loro verifica sono quelli classici: MASM o TASM, LINK o TLINK, un EDITOR ASCII, un compilatore Borland PASCAL da 4.0 a 7.0 oppure DELPHI 1.0. Ogni funzione/procedura può essere scaricata ed usata così com'è o modificata a proprio piacimento per uso personale. In caso di utilizzo in pagine Web si raccomanda di NON alterare l'intestazione con i riferimenti all'Autore/Proprietario e si gradisce un Link a questo sito o una e-mail. Questo materiale viene reso disponibile FREEWARE o meglio CAREWARE, secondo la definizione datane da Paul Lutus .
Function XCharCountSt(Ch: Char; St: String): Integer;
Legge il numero di ricorrenze del carattere Ch all'interno della stringa St, se Ch non esiste restituisce 0.
Es.: I:=XCharCountSt('A','FARFALLA'); restituisce I=3

Function XCharCountPtr(Ch: Char; Var Pt; L: Word): Integer;
Legge il numero di ricorrenze del carattere Ch all'interno dell'area di memoria puntata da Pt ed estesa L byte, se Ch non esiste restituisce 0.
Es.: I:=XCharCountPtr(Ch,Ptr,L);

Function XCharPos(Ch: Char; St: String): Integer;
Legge la posizione del carattere Ch all'interno della stringa St, se Ch non esiste restituisce 0. Analoga alla Pos(Q,St) del TurboPascal, ma più veloce. Da provare. Aumenta l'efficienza se utilizzata al posto di XPos.
Es.: I:=XCharPos('R','VERDERAME'); restituisce I=3

Function XPos(Q,St: String): Integer;
Legge la posizione della stringa Q all'interno della stringa St, se Q non esiste restituisce 0. Analoga alla Pos(Q,S) del TurboPascal, ma più veloce. Da provare.
Es.: I:=XPos('xyz','ABCDxyzEFG'); restituisce I=5

Function XMegaPos(Q: String; Var MSt; K: Word): Word;
Legge la posizione della stringa Q all'interno della Megastringa MStL, se esiste, altrimenti restituisce 0. K=1,2,3,.... rappresenta la ricorrenza ricercata. Per Megastringa si intende una struttura definita da una word, per la lunghezza, e da un insieme di byte che contiene i byte; questa definizione consente il superamento del limite dei 255 byte della tipica stringa Pascal che nella sua struttura ha un byte come lunghezza.
Es.: I:=XMegaPos(Q,MStL,2); Cerca la seconda ricorrenza di Q in MStL.

Function XSearch(Q: String; Pseg,Pofs,L: Word): Word;
Legge la posizione della stringa Q all'interno dell'area puntata da Pseg:Pofs ed estesa L byte, se Q non esiste restituisce 0. Scritta a puro titolo di esercitazione, i valori di Pseg e Pofs sono ricavabili in Pascal tramite le funzioni Seg e Ofs applicate ad una variabile.
Es.: I:=XSearch(Q,Pseg,Pofs,Len);

Function XScanText(C: Word; P: Pointer; L: Word): Word;
Cerca nell'area puntata da P e lunga L byte una zona di Testo caratterizzata dalla presenza di C caratteri alfanumerici consecutivi. Usata per cercare nella RAM zone caratterizzate dalla presenza di possibile testo significativo
Es.: W:=XScanText(5,Ptr,Len); Cerca una zona con almeno 5 caratteri alfanumerici consecutivi.

Function XScanNoText(C: Word; P: Pointer; L: Word): Word;
Cerca nell'area puntata da P e lunga L byte una zona di Non-Testo caratterizzata dalla assenza di C caratteri alfanumerici consecutivi. E' la complementare della XScanText.
Es.: W:=XScanNoText(10,Ptr,Len);

Function XInstr(P: Byte; Q,St: String): Integer;
Cerca la stringa Q all'interno della stringa St, cominciando la ricerca dalla posizione P, se esiste, altrimenti restituisce 0. Analoga alla INSTR del BASIC.
Es.: I:=XInstr(P,Q,St);

Function XCompress(St: String): String;
Comprime la Stringa St col metodo "Run Length Encoding". Il carattere di controllo usato è FFh che quindi non deve essere presente in St.
Es.: Xt:=XCompress(St);

Function XDeCopress(St: String): String;
Complementare di XCompress. Le due funzioni sono state scritte a titolo di esercizio, nel caso del testo la compressione RLE risulta generalmente inefficiente.
Es.: Xt:=XDeCompress(St);

Function XCripto(St: String; C: Byte): String;
Crittografa con chiave C la stringa St. Obsoleta, utilizzare XCriptoDe.
Es.: Xt:=XCripto(St,C);

Function XDeCripto(St: String; C: Byte): String;
Decrittografa con chiave C la stringa St. Obsoleta, utilizzare XCriptoDe.
Es.: Xt:=XDeCripto(St,C);

Function XCriptoDe(St: String; C: String): String;
Crittografa/Decrittografa con chiave C la stringa St. Da preferire alla coppia XCripto-XDeCripto nelle nuove applicazioni. Se il testo da crittografare è prevalentemente minuscolo evitare una chiave con caratteri minuscoli e viceversa. Due applicazioni successive di XCriptoDe ripristinano la stringa originaria.
Es.: Xt:=XCriptoDe('Prova di Crittografia','SEGRETO'); restituisce: W!*13e0&'C7.&1;(u2#.3
Xt:=XCriptoDe('W!*13e0&'C7.&1;(u2#.3','SEGRETO'); restituisce: Prova di Crittografia

Function XTab(St: String; N: Byte): String;
Inserisce i caratteri TAB in St.
Es.: Xt:=XTab(St);

Function XDeTab(St: String; N: Byte): String;
Complementare di XTab.
Es.: Xt:=XDeTab(St,8);

Function XMerge(Q,St: String; P: Byte): String;
Sovrappone la stringa Q sulla stringa St dalla posizione P in avanti. Se P <= 0, St rimane inalterata.
Es.: Xt:=XMerge('argento','VERDERAME',6); restituisce Xt='VERDEargento'

Function XMergeCut(Q,St: String; P: Byte): String;
Sovrappone la stringa Q sulla stringa St dalla posizione P in avanti. Se Q è troppo lunga si sovrappone su St solo quella prima parte di Q che vi può essere contenuta. Se P <= 0, St rimane inalterata.
Es.: Xt:=XMergeCut('argento','VERDERAME',6); restituisce Xt='VERDEarge'

Function XNoChar(Ch: Char; St: String): String;
Elimina dalla stringa St i caratteri Ch.
Es.: Xt:=XNoChar('a','Farfalla'); restituisce Xt='Frfll'

Function XNoCharCo(Ch: Char; St: String): String;
Elimina i caratteri Ch in Coda a St.
Es.: Xt:=XNoCharCo('a','Farfallaaaaaaa'); restituisce Xt='Farfall'

Function XNoCharTe(Ch: Char; St: String): String;
Elimina i caratteri Ch in Testa a St.
Es.: Xt:=XNoCharTe('0','0005675'); restituisce Xt='5675'

Function XNoCharSet(Q,St: String): String;
Elimina dalla stringa St tutti i caratteri contenuti nella stringa Q.
Es.: Xt:=XNoCharSet('abcd','Roma caput mundi'); restituisce Xt='Rom put muni'

Function XYesCharSet(Q,St: String): String;
Elimina dalla stringa St i caratteri diversi da quelli contenuti nella stringa Q.
Es.: Xt:=XYesCharSet('abcd','Roma caput mundi'); restituisce Xt='a ca d'

Function XLFill(Ch: Char; St: String; N: Byte): String;
Premette alla stringa St tanti caratteri Ch per una lunghezza complessiva N. Se Length(St) >= N, St rimane inalterata.
Es.: Xt:=XLFill(Ch,St,N);

Function XRFill(Ch: Char; St: String; N: Byte): String;
Accoda alla stringa St tanti caratteri Ch per una lunghezza complessiva N. Se Length(St) >= N, St rimane inalterata.
Es.: Xt:=XRFill('x','ARCOBALENO',15); restituisce Xt='ARCOBALENOxxxxx'

Function XNoSpace(St: String): String;
Elimina i caratteri spazio Inclusi in St.
Es.: Xt:=XNoSpace(' Roma caput mundi '); restituisce Xt='Romacaputmundi'
Es.: * char far *XNoSpace(char far *St);

Function XNoSpaceCo(St: String): String;
Elimina i caratteri spazio in Coda a St.
Es.: Xt:=XNoSpaceCo(' Roma caput mundi '); restituisce Xt=' Roma caput mundi'
Es.: * char far *XNoSpaceCo(char far *St);

Function XNoSpaceTe(St: String): String;
Elimina i caratteri spazio in Testa a St.
Es.: Xt:=XNoSpaceTe(' Roma caput mundi '); restituisce Xt='Roma caput mundi '
Es.: * char far *XNoSpaceTe(char far *St);

Function XMonoSpa(St: String, T: Byte): String;
Riduce a uno gli spazi consecutivi in St. Se T=0 vengono eliminati tutti gli spazi di testa e di coda.
Es.: Xt:=XMonoSpa(' Il canto delle sirene ',1); restituisce Xt=' Il canto delle sirene '
Es.: Xt:=XMonoSpa(' Il canto delle sirene ',0); restituisce Xt='Il canto delle sirene'

Function XPack(St: String): String;
Elimina i caratteri spazio e converte St in maiuscole.
Es.: Xt:=XPack(' Roma caput mundi '); restituisce Xt='ROMACAPUTMUNDI'

Function XLSet(St: String; N: Byte): String;
Accoda alla stringa St tanti spazi fino a raggiungere una lunghezza complessiva N. Se Length(St) > N ricopia i primi N caratteri di St, tagliando la coda.
Es.: Xt:=XLSet('Arcobaleno',15); restituisce Xt='Arcobaleno '

Function XRSet(St: String; N: Byte): String;
Inserisce prima della stringa St tanti spazi fino a raggiungere una lunghezza complessiva N. Se Length(St) > N ricopia gli ultimi N caratteri di St, tagliando la testa.
Es.: Xt:=XRSet('Arcobaleno',15); restituisce Xt=' Arcobaleno'

Function XLeftS(St: String; N: Byte): String;
Restituisce la parte sinistra di St (primi N caratteri). Analaga alla LEFT$ del BASIC.
Es.: Xt:=XLeftS('ARCOBALENO',4); restituisce Xt='ARCO'

Function XRightS(St: String; N: Byte): String;
Restituisce la parte destra di St (ultimi N caratteri). Analaga alla RIGHT$ del BASIC.
Es.: Xt:=XRightS('ARCOBALENO',6); restituisce Xt='BALENO'

Function XString(N: Integer; Ch: Char): String;
Genera una stringa di N caratteri Ch.
Es.: Xt:=XString(10,'z'); restituisce Xt='zzzzzzzzzz'

Function XCenterStr(St: String; F: Byte): String;
Centra la stringa St, lunga L byte, in un campo ampio F byte. La funzione premette a St (F-L)/2 spazi. St resta inalterata nei seguenti casi:
  • Length(St) = 0
  • Length(St) >= F
  • L + (F-L)/2 > 255
    Es.: Xt:=XCenterStr('ARCOBALENO',20); restituisce Xt=' ARCOBALENO'

    Function XSpaceStr(St: String): String;
    Alterna con spazi i caratteri della stringa St. St resta inalterata nei seguenti casi:
  • Length(St) = 0
  • Length(St) > 128.
    Es.: Xt:=XSpaceStr('MILANO'); restituisce Xt='M I L A N O'

    Function XChange(St: String; Ch,NCh: Char): String;
    Scambia in St tutti i caratteri Ch con NCh e viceversa. Si noti la differenza con XStrip.
    Es.: Xt:=XChange('122234567778','2','7'); restituisce Xt='177734562228'
    Es.: Xt:=XStrip('122234567778','2','7'); restituisce Xt='177734567778'

    Function XStrip(St: String; Ch,NCh: Char): String;
    Cambia in St tutti i caratteri Ch con NCh. Vedi anche XChange.
    Es.: Xt:=XStrip('FARFALLA','A','a'); restituisce Xt='FaRFaLLa'

    Function XStSubst(QSt,PSt: String; Var St: String): Boolean;
    Cambia in St la prima ricorrenza di QSt con PSt, restituisce TRUE se è avvenuta la sostituzione altrimenti FALSE.
    Es.: B:=XStSubst('ABC','xyzkc',St);

    Function XSwapS(St: String; X,Y: Byte): String;
    Scambia di posto in St i caratteri aventi le posizioni X e Y.
    Es.: Xt:=XSwapS('ABCDEFG',2,3); restituisce Xt='ACBDEFG'

    Function XMirror(St: String): String;
    Riflette la stringa St: l'ultimo carattere diviene il primo, il penultimo il secondo e così via.
    Es.: Xt:=XMirror('ARCOBALENO'); restituisce Xt='ONELABOCRA'

    Function XUpCase(St: String): String;
    Converte in Maiuscole i caratteri di St.
    Es.: Xt:=XUpCase('Milano'); restituisce Xt='MILANO'
    Es.: * char far *XUpCase(char far *St);

    Function XUpCaseW(St: String,F: Byte): String;
    Converte in Maiuscole le iniziali delle parole di St. Se F=0 le uniche maiuscole presenti in uscita saranno le iniziali.
    Es.: Xt:=XUpCaseW('MILANO torino',0); restituisce Xt='Milano Torino'
    Es.: Xt:=XUpCaseW('MILANO torino',1); restituisce Xt='MILANO Torino'

    Function XLoCase(St: String): String;
    Converte in Minuscole i caratteri di St.
    Es.: Xt:=XLoCase('CAVALLO'); restituisce Xt='cavallo'
    Es.: * char far *XLoCase(char far *St);

    Function XUpLoCase(St: String): String;
    Scambia in St le maiuscole in minuscole e viceversa.
    Es.: Xt:=XUpLoCase('Roma'); restituisce Xt='rOMA'

    Function XNotStr(St: String): String;
    Applica ai caratteri di St l'operatore NOT.
    Es.: Xt:=XNotStr('MILANO'); restituisce Xt='▓Â│ż▒░'

    Function XRotStrR(St: String): String;
    Ruota Circolarmente verso Destra la stringa St.
    Es.: Xt:=XRotStrR('GENOVA'); restituisce Xt='AGENOV'

    Function XRotStrL(St: String): String;
    Ruota Circolarmente verso Sinistra la stringa St.
    Es.: Xt:=XRotStrR('GENOVA'); restituisce Xt='ENOVAG'

    Function XHexStr(Var N; K: Word): String;
    Converte il numero N (formato da K byte) in una stringa di 2*K caratteri Hex.
    Es.: Xt:=XHexStr(N,K);

    Function XHexStrB(B: Byte): String;
    Converte il numero N (byte) in una stringa di 2 caratteri Hex. Specifica e più veloce, da usarsi al posto della generica XHexStr quando si stanno trattando esclusivamente byte.
    Es.: Xt:=XHexStrB(157); restituisce Xt='9D'

    Function XHexStrW(W: Word): String;
    Converte la word W in una stringa di 4 caratteri. Specifica e più veloce, da usarsi al posto della generica XHexStr quando si stanno trattando esclusivamente word.
    Es.: St:=XHexStrW(W);

    Function XWordCount(St: String): Word;
    Conta il numero di parole contenute nella stringa St. L'elemento separatore è lo spazio.
    Es.: W:=XWordCount('Bella, la primavera'); restituisce W=3

    Procedure XStrAsciiz(St: String; Var V);
    Trasforma la stringa Pascal St in una ASCIIZ collocata in V.
    Es.: XStrAsciiz('Pippo'; Var V);
    Pone in V l'equivalente Assembler di: DB "Pippo",0

    Procedure XStrAsciiz32(St: String; Var V);
    Trasforma la stringa Pascal St in una ASCIIZ collocata in V. V sarà sempre portata a 32 byte con l'aggiunta di Zeri. La stringa in input sarà troncata al 31mo carattere, se più lunga. Sviluppata esclusivamente per l'ambiente DataEasy.
    Es.: XStrAsciiz('Pippo'; Var V);
    Pone in V l'equivalente Assembler di: DB "Pippo",27 DUP(0)

    Function XAsciizStr(Var V): String;
    Trasforma la stringa ASCIIZ collocata in V in una stringa Pascal.
    Es.: St:=XAsciizStr(V);
    Se V è l'equivalente Assembler di: DB "Pippo",0 rende St:='Pippo'


    Function XAllPath(N: String): String;
    Restituisce il Pathname completo della directory N che può essere indicata anche in modo relativo alla directory corrente e includere anche il nome del drive. Se la directory N non esiste o è specificata in modo errato viene restituita una stringa nulla.
    Es.: St:=XAllPath('C:') restituisce la directory corrente del disco C:

    Function XCreatF(T: Word; Var St): Word;
    Crea il file DOS a lunghezza variabile di nome St associandogli la word H (Handle). T=0 Normal, T=1 ReadOnly, T=2 Hidden, T=3 ReadOnly+Hidden, T=4 System

    Function XOpenF(T: Word; Var St): Word;
    Apre il file DOS a lunghezza variabile di nome St associandogli la word H (Handle). T=2 ReadWrite, T=1 WriteOnly, T=0 ReadOnly

    Function XSizeF(H: Word): LongInt;
    Legge in L (LongInt) la lunghezza in byte del file DOS di Handle=H

    Procedure XSeekF(H: Word; M: Byte; N: LongInt);
    Sposta in avanti di N (LongInt) byte il puntatore del file DOS di Handle=H, con modalità M: 0 - dall'inizio del file 1 - dalla posizione corrente 2 - dalla fine del file Se N è negativo il puntatore si sposta a ritroso.

    Procedure XReadF(H: Word; Var Bf; N: Word; Var C: Word);
    Legge dal file DOS di Handle=H N byte ponendoli nel Buffer Bf. C riporta il numero dei byte effettivamente letti.

    Procedure XWriteF(H: Word; Var Bf; N: Word; Var C: Word);
    Scrive sul file DOS di Handle=H N byte prelevandoli dal Buffer Bf. C riporta il numero dei byte effettivamente scritti.

    Procedure XCloseF(H: Word);
    Chiude il file DOS individuato da H (Handle).

    Function XCopyF(N1,N2: String): Boolean;
    Copia il file di nome N1 in N2. Restituisce True se l'operazione va a buon fine. Il file copiato riporta la stessa data e ora del sorgente.
    Es.: B:=XCopyF('Myfile','Myfile.bak')
    genera una copia di scorta di Myfile e restituisce B=True

    Function XCompF(N1,N2: String): Byte;
    Confronta i file di nome N1 ed N2. Restituisce 0 se l'operazione va a buon fine ed i file sono identici byte a byte. Altrimenti restituisce: 1: se N1 non esiste 2: se N2 non esiste 3: se N1 ed N2 hanno dimensioni diverse 4: se N1 ed N2 non sono coincidenti
    Es.: B:=XCompF('Myfile1','Myfile2')


    Function XMoveF(P1,P2: String): Byte;
    Sposta il file da path P1 a P2. Restituisce 0 se l'operazione va a buon fine, altrimenti il codice d'errore. Sono ammessi i caratteri jolly; gli spostamenti avvengono all'interno di uno stesso disco. Se P2='' il file viene spostato nella directory corrente. Codici di errore: 2,18: File non trovato 3: Path non trovato 5: Accesso negato 17: Drive diversi altri: Errore su P1
    Es.: B:=XMoveF('\WORK\Myfile','\LAB')
    sposta il file Myfile dalla directory WORK alla directory LAB.

    Function XTxtFilePos(Var F: Text): LongInt;
    Restituisce la posizione corrente del file Testo F. E' l'analoga di FilePos per gli altri tipi di file.

    Procedure XTxtSeek(Var F: Text; SeekLoc: LongInt);
    Posiziona la posizione corrente di un file Testo ad un componente specificato. E' l'analoga di Seek per gli altri tipi di file.

    Function XTxtFileSize(Var F: Text): LongInt;
    Restituisce la dimensione corrente di un file Testo. E' l'analoga di FileSize per gli altri tipi di file. Il file deve essere aperto.

    Function XScrollF(N: String; C,M,X: Byte): Byte;
    Visualizza il file-testo di nome N sul video, con attributi colore C. L'operatore M, interpretato in binario Ő la modalitů operativa: 00000000 modo normale 00000001 file testo crittografato con byte X 00000010 scroll di singola riga bloccato (verticale) 00000100 scroll orizzontale bloccato 00001000 selezione messaggio help 00010000 opzione Roll-Down ON se presente EOF=1Ah E' possibile lo scorrimento del testo sia in verticale sia in orizzon- tale (righe maggiori di 80 caratteri). La visualizzazione si conclude col tasto ESC, mentre F1 visualizza un minihelp. Restituisce 6 codici possibili: 0 operazione riuscita 1 file non trovato 2 modo video non ammesso (Modi Legali: 0,1,2,3,7) 3 memoria insufficiente 4 errore di chiusura file (Raro) 5 memoria non rilasciata (Raro) Utilizzare la direttiva di compilazione {$M}, ad esempio {$M 8192,0,0}
    Es.: B:=XScrollF('MYFILE',$1E)
    visualizza il file MYFILE in giallo su fondo blu.

    Function XScanF(N: String; D: Char; L,V: Byte): Word;
    Cerca conta e visualizza (se V>0) il pathname completo dei file di nome N presenti sul drive D. La ricerca parte dalla Radice (Livello 0) e si spinge fino alle sottodirectory di livello L (max 15). La funzione restituisce il numero di file N trovati. N puĽ contenere anche caratteri Jolly.
    Es.: W:=XScanF('MYFILE','C',4,0)
    conta la presenza di MYFILE sul drive C: dalla radice fino al 4° livello.

    Function XDirF(Path,FOut: String; M: Byte; T: Word): Word;
    Riporta su FOut i nomi delle voci della directory Path. La Fun- zione restituisce il numero di voci trovate, incluso il nome del Volu- me se presente. Il parametro M consente di selezionare le modalita' di ricerca: M = 6 Volume+Directory M = 4 Volume ┌─┬─┬─┬─┬─┬─┬─┬─┐ M = 3 Directory+File Byte M │-│-│-│-│-│V│D│F│ M = 2 Directory à─┴─┴─┴─┴─┴─┴─┴─ù M = 1 File Se T=0 l'uscita avviene sul File FOut, con le seguenti eccezioni: se FOut='CON' l'output avviene sul video se FOut='LPT1' l'output avviene sulla stampante Se T<>0 l'uscita avviene sulla matrice FOut di T elementi stringa di lunghezza 47, utilizzare in questo caso il primo elemento di FOut come parametro stringa (FOut[1]). In caso di errore su FOut la funzione restituisce: $FFFF in caso di nome file nullo $FFFE in caso di array insufficiente
    Es.: W:=XDirF('C:*.PAS','CON',3,0) uscita su video

    Es.: W:=XDirF('C:*.PAS','LPT1',3,0) uscita su stampante

    Es.: W:=XDirF('C:*.PAS','MYFILE',3,0) uscita su file MYFILE

    Es.: W:=XDirF('C:*.PAS',M[1],3,20) uscita su array M


    Function XWipeF(N: String): Boolean;
    Azzera il file di nome N. Restituisce True se l'operazione va a buon fine. Il file non viene rimosso dalla directory.
    Es.: B:=XWipeF('Myfile');


    Procedure XCriptoF(St1,St2: String; Shift: Byte);
    Esegue la copia crittografata di N1 in N2. Shift Ő una costante di inizializzazione da utilizzare anche con la procedura complementare XDeCriptoF.
    Es.: XCriptoF('MyText','Secret',37);


    Procedure XDeCriptoF(St1,St2: String; Shift: Byte);
    Complementare della XCriptoF.
    Es.: XDeCriptoF('Secret','Clear',37);


    Function XKillF(N: String): Boolean;
    Rimuove dalla directory il file di nome N. Restituisce True se l'opera- zione va a buon fine.
    Es.: B:=KillF('Myfile');


    Function XExist(FN: String): boolean;
    Restituisce True se il file di nome St esiste, altrimenti False.
    Es.: L:=XExist(St);


    Procedure XCompressText(St1,St2: String; Var Perc: Real);
    Comprime il file di nome St1 nel file St2, con il metodo RLE (vedi XCompress in TpuStr). P Ő la percentuale di compressione.
    Es.: XCompressText(St1,St2,P);


    Procedure XDeCompressText(St1,St2: String; Var Perc: Real);
    Complementare della XCompressText.
    Es.: XDeCompressText(St1,St2,P);


    Procedure XSetVerify(B: Boolean);
    Attiva/Disattiva lo switch DOS VERIFY. Se VERIFY Ő attivo il DOS legge i byte CRC (Cyclic Redundancy Check) dei dati appena scritti e verifi- ca che essi siano corretti. L'attivazione di VERIFY non causa, come comunemente si crede, una let- tura dopo la scrittura dei dati su disco, ma solo una verifica dei by- te di CRC. I Dischi in Rete non supportano la funzione VERIFY.
    Es.: XSetVerify(True);


    Function XGetVerify: Boolean;
    Riporta lo stato del flag VERIFY dopo una scrittura su disco.
    Es.: B:=XGetVerify;


    Function XRedirOut(N: String): Boolean;
    Ridireziona l'Output Standard sul file di nome N.
    Es.: B:=XRedirOut('NEWOUT');


    Function XNormOut: Boolean;
    Ripristina L'Output Standard;
    Es.: B:=XNormOut;


    Function XDiskVerify(NS,D,T,S,H: Byte): Byte;
    Verifica direttamente tramite int 13h il disco del drive D, alla traccia T, Settore S, Testina H, Numero di Settori NS.

    Function XDiskVerifyCrp(NS,D,T,S,H: Byte): Byte;
    Come XDiskVerify, ma con Int 13h Krp.

    Function XDiskRead(Var BF; Var NSR,Err: Byte; NS,D,T,S,H: Byte): Byte;
    Legge direttamente tramite int 13h il disco del drive D, alla traccia T, Settore S, Testina H, Numero di Settori NS. Restituisce la lettura nel Buffer BF, il numero di settori letti in NSR, il codice di errore in Err.

    Function XDiskReadCrp(Var BF; Var NSR,Err: Byte; NS,D,T,S,H: Byte): Byte;
    Come XDiskRead, ma con Int 13h Krp.

    Function XDiskWrite(Var BF; Var NSW,Err: Byte; NS,D,T,S,H: Byte): Byte;
    Scrive direttamente tramite int 13h il Buffer BF su disco del drive D, alla traccia T, Settore S, Testina H, Numero di Settori NS. Restituisce il numero di settori scritti in NSW, il codice di errore in Err.

    Function XDiskWriteCrp(Var BF; Var NSW,Err: Byte; NS,D,T,S,H: Byte): Byte;
    Come XDiskWrite, ma con Int 13h Krp.

    Function XDiskReset(D: Byte): Byte;
    Effettua Reset Drive D.

    Function XDiskResetCrp(D: Byte): Byte;
    Come XDiskReset, ma con Int 13h Krp.

    Function XReadSector(Var BF; D,S,N: Word): Word;
    Legge nel Buffer BF, tramite int 25h, N settori del disco del drive D a partire dal settore S. Restituisce 0 se l'operazione va a buon fine altrimenti la Word d'errore.

    Function XWriteSector(Var BF; Drive,Sector,Number: Word): Word;
    Scrive in Buffer BF, tramite int 26h, N settori dal disco del drive D a partire dal settore S. Restituisce 0 se l'operazione va a buon fine altrimenti la Word d'errore.

    Function XGetDrive: String;
    Restituisce una stringa contenente le lettere dei drive riconosciuti dal DOS (Lettori, RamDisk, etc.).
    Es.: St:=XGetDrive;