ELABORATORI ELETTRONICI (v. calcolatrici, macchine, VIII, p. 352; App. I, p. 339; II, 1, p. 482; III, 1, p. 281)
Negli ultimi anni si sono straordinariamente diffuse calcolatrici elettroniche di piccolissime dimensioni e di grandi prestazioni, le cosiddette calcolatrici tascabili o da tavolo. Queste macchine, la cui realizzazione e i cui incessanti processi sono da ascrivere ai grandi passi fatti dalla tecnologia elettronica, hanno reso familiare la struttura di una calcolatrice e il modo di usarla: mediante una tastiera s'introducono dei numeri rappresentati in notazione decimale con virgola e segno e, mediante la pressione di appositi tasti, si provoca l'esecuzione di operazioni aritmetiche o di altre assai più complesse (trigonometriche, logaritmiche, ecc.) fra i numeri contenuti nei registri della calcolatrice (dove per "registro" s'intende un dispositivo capace d'immagazzinare un dato numerico o di altro tipo).
Queste macchine eseguono un'operazione alla volta e l'eseguono per effetto dell'azionamento del tasto corrispondente all'operazione stessa. Dovendo eseguire lunghe sequenze di operazioni si ha, in alcune di queste calcolatrici, la possibilità di registrare la sequenza su un apposito supporto amovibile (per es. una strisciolina di nastro magnetico) usando la calcolatrice stessa. Successivamente si può introdurre uno di tali supporti dentro la calcolatrice per far eseguire la sequenza di operazioni registrata sul supporto stesso.
In tal modo si arriva ad avere ciò che viene chiamato calcolatore automatico, cioè un dispositivo (elettronico oggi) capace di eseguire automaticamente una sequenza di operazioni in base a un "programma" registrato in una sua memoria e composto di istruzioni. Le istruzioni specificano ciascuna l'operazione da compiere e i registri sui cui contenuti devono essere compiute tali operazioni.
Quando il calcolatore può operare oltre che su numeri anche su caratteri alfabetici o più in generale su "dati" si ha un elaboratore di dati o elaboratore, o e. e., o elaboratore automatico.
Poiché a ciascun tipo di dato è associabile un insieme di relazioni e operazioni che formano una "struttura di dati" (v. informatica, in questa App.), possiamo dire che un e. è un sistema capace di eseguire automaticamente programmi di operazioni relativi a una o più strutture di dati (caratteri, bit, numerali a notazione decimale o binaria, con virgola fissa o mobile, ecc.).
Gli e. e. più semplici hanno una struttura simile a quella delle calcolatrici elettroniche usuali. Ricordiamo che si possono distinguere le seguenti unità funzionali (fig. 1):
1) Memoria di lavoro: è un insieme di registri (contraddistinti da numeri interi, detti "indirizzi") nei quali si possono registrare (o scrivere, come si dice) dei dati e dai quali questi possono essere letti per essere trasferiti ad altre unità e organi dell'elaboratore. Tale memoria può contenere sia operandi sia istruzioni e perciò i programmi possono essere oggetto di elaborazione, il che è un fatto assai importante, come vedremo.
Anche se negli organi di memoria i dati elementari sono cifre binarie (o bit), in genere gl'indirizzi non si riferiscono al singolo bit, ma a sequenze di bit in numero di 6 o 8 dette "caratteri" (o, nel caso di 8, "byte") oppure a sequenze di 16, 24, 32, 36, 48, 60, ecc., bit, dette parole o voci.
Il nome di "carattere" deriva dal fatto che con 6 bit si possono rappresentare 26 = 64 oggetti diversi e in particolare perciò i caratteri di un usuale alfabeto; lettere, cifre e altri segni. I caratteri sono il tipo di dato più conveniente in elaborazioni di testi qualunque e in elaborazioni di tipo gestionale in genere.
Le parole invece convengono per elaborazioni numeriche in quanto possono rappresentare numeri nell'intervallo da − 2n-1 a + 2n-1 se n è il numero di bit della parola e la rappresentazione è quella detta in virgola fissa (v. calcolatrici, macchine, App. III, 1, p. 284). Una parola in genere corrisponde anche a un'istruzione.
2) Unità aritmetica e logica: serve a compiere tutte le varie operazioni corrispondenti alle istruzioni dell'e., che possono essere da alcune decine ad alcune centinaia.
3) Unità di governo (o di controllo): cura l'esecuzione ordinata delle istruzioni del programma che viene eseguito dall'elaboratore. Comprende in genere un contatore delle istruzioni, in cui è registrato l'indirizzo del registro di memoria che contiene l'istruzione da eseguire, un registro istruzione che contiene quest'ultima, un decodificatore che decodifica l'operazione specificata dall'istruzione e organi sequenziatori che curano il succedersi delle varie fasi in cui si decompone usualmente l'esecuzione di un'istruzione. È da notare che spesso l'insieme costituito da unità di governo e unità aritmetica e logica è detto "unità centrale".
In alcuni casi l'esecuzione di ogni istruzione viene decomposta nell'esecuzione di diverse operazioni più semplici specificate ciascuna da un'istruzione più elementare detta microistruzione. Perciò l'esecuzione di ogni istruzione viene specificata da un "microprogramma" composto di microistruzioni. Tale microprogramma è contenuto in un organo detto memoria fissa o memoria a sola lettura, in quanto si comporta come una memoria di cui non viene mai alterato il contenuto.
4) Canali per il collegamento della memoria alle varie unità periferiche di cui qui nel seguito.
5) Unità periferiche e loro organi di governo. Per unità periferiche s'intendono unità (spesso di tipo elettromeccanico anziché totalmente elettroniche come le altre) per l'ingresso e l'uscita di dati (lettori o perforatori di schede o di nastri di carta, stampanti, telescriventi, tastiere, schermi video, ecc.) oppure per funzioni di memoria sussidiaria, quali le unità a nastri o a dischi magnetici. Queste ultime unità hanno supporto fisico magnetizzabile (un nastro di plastica, o un insieme di dischi metallici sovrapposti su uno stesso asse) su cui si possono scrivere o da cui si possono leggere dei dati. Se il supporto è asportabile allora l'unità può essere usata anche come unità d'ingresso e uscita oltre che come memoria sussidiaria.
La divisione della memoria di un e. in memoria di lavoro o principale e memoria sussidiaria o secondaria è legata al fatto che la prima ha tempi di accesso brevi (dell'ordine del microsecondo) e costi maggiori (dell'ordine della lira per bit, ai prezzi 1975) mentre le memorie sussidiarie hanno tempi di accesso mille e più volte maggiori e costi corrispondentemente minori.
Una memoria di lavoro ha in genere una capacità che va da qualche migliaio a qualche milione di caratteri. Una bobina di nastro magnetico può contenere fino a varie decine di milioni di caratteri, un pacco di dischi fino a qualche centinaio di milioni di caratteri (1976).
Attualmente nel campo degli e. e. si può delineare la seguente gerarchia di capacità elaborative, di complessità di struttura e di costi:
A) Microelaboratori. Sono formati da una o poche piastrine di elettronica integrata, a silicio, ciascuna dell'area di circa 20 mm2. Hanno capacità di memoria principale dell'ordine delle decine di migliaia di caratteri o di parole, eseguono solo le operazioni aritmetiche più semplici e hanno un limitato repertorio di istruzioni. A parte le unità periferiche, hanno costi dell'ordine di centinaia di migliaia di lire (1976). Dati i costi e le dimensioni, i microelaboratori, che sono apparsi sul mercato solo negli ultimissimi anni, sono destinati a entrare ampiamente nella strumentazione elettronica e nell'automazione sia industriale sia di ufficio.
B) Minielaboratori. Hamno capacità e dimensioni maggiori (anche perché talora usano tecnologie che dànno una minore densità di componenti) e costi dell'ordine dei milioni di lire (1976). Con il diffondersi delle tecnologie della microelettronica la distinzione fra essi e i microelaboratori tende a sfumare.
C) Elaboratori del tipo su descritto, con memorie, velocità operative e numero di unità periferiche più o meno grandi.
D) Multielaboratori composti da più elaboratori (da alcuni ad alcune centinaia) che operano concorrentemente o su un unico lavoro o condividendosi un carico comune di lavori mutuamente indipendenti.
Programmazione. - Uno dei problemi fondamentali della programmazione è il seguente: dato che un e. può eseguire in un secondo decine di migliaia o anche milioni delle proprie istruzioni, e dato che un programmatore che redige un programma scrive istruzioni a velocità certamente inferiori a un'istruzione al minuto, come si fa a sfruttare tutta la velocità di un e. senza dover avere un numero assurdo di programmatori?
La risposta è nel fatto che i programmi sono redatti in modo parametrico sia rispetto agli operandi sia rispetto alle risorse (memoria, unità periferiche, ecc.) del sistema, sono eseguiti in modo ripetitivo e redatti in modo di essere componibili modularmente.
La parametricità rispetto agli operandi è data innanzitutto dal tipo d'istruzione proprio degli e. che non fa riferimento diretto agli operandi, ma all'indirizzo del registro che li contiene. Così, un'istruzione di somma potrà avere la forma
ADD 3 00324,
dove ADD è la "parte operazione" che specifica che occorre fare un'addizione registrando il risultato nell'accumulatore 3 dell'unità aritmetica e logica, e dove 00324 è la "parte indirizzo" dell'istruzione che dà l'indirizzo del registro di memoria il cui contenuto dev'essere sommato a quello dell'accumulatore 3 stesso.
Tale istruzione è indipendente dal valore degli addendi, ovviamente.
Se occorresse leggere 1000 numeri da schede e sommarli fra loro non si dovrebbero dare 1000 istruzioni di lettura e di somma al contenuto dell'accumulatore, ma basterebbe dare 1000 volte una stessa coppia di istruzioni:
LEG 00324
ADD, 3,00324,
delle quali la prima specifica di leggere un numero da scheda nel registro di memoria d'indirizzo 00324 e la seconda di sommare il contenuto di tale registro a quello dell'accumulatore 3, che si suppone inizialmente nullo.
Per fare in modo che la suddetta coppia di istruzioni sia eseguita 1000 volte si può usare un altro accumulatore per tenere questo conteggio e cessare di ripetere l'esecuzione della coppia quando si è raggiunto tale numero.
La rilevazione di ciò può essere attuata mediante le "istruzioni di salto condizionato", che alterano l'ordine normale di esecuzione delle istruzioni in dipendenza dell'avverarsi o no di una certa condizione. L'ordine normale è quello in cui le istruzioni sono registrate in memoria: dopo l'istruzione registrata nell'indirizzo k viene normalmente eseguita quella in k + 1 e ciò è effettuato dal contatore delle istruzioni del governo il cui contenuto (che indica appunto l'indirizzo che contiene l'istruzione da eseguire) viene aumentato di 1 durante l'esecuzione di ogni istruzione.
Quando, però, viene eseguita un'istruzione di salto condizionato e la condizione è soddisfatta (oppure quando è eseguita un'istruzione di salto incondizionato) la parte indirizzo dell'istruzione di salto dà l'indirizzo della prossima istruzione da eseguire. L'esecuzione di un'istruzione di salto perciò consiste nell'invio della sua parte indirizzo nel contatore delle istruzioni.
Qui di seguito diamo un semplice repertorio di istruzioni per un ipotetico elementare elaboratore. Le istruzioni sono del tipo a un indirizzo, cioè contengono un solo riferimento alla memoria, secondo lo schema:
OP, A, IND
dove OP è la "parte operazione" che specifica l'operazione da eseguire, A indica uno di quattro accumulatori dell'unità aritmetica (con indirizzi da 0 a 3), IND è la "parte indirizzo" e specifica l'indirizzo che contiene uno degli operandi.
Si noti come spesso si abbrevia la frase "contenuto del registro di memoria di indirizzo IND" nell'altra "contenuto di IND".
Descritto il repertorio delle istruzioni, vediamo un esempio di programma per il calcolo della somma di n numeri letti da altrettante schede. Il programma è parametrico sia rispetto ai numeri da sommare sia rispetto a n, che è registrato nella prima scheda letta. La somma è effettuata nell'accumulatore 3, mentre l'accumulatore 2 è usato per conteggiare i numeri sommati.
Si noti che la prima colonna non fa parte del programma, ma indica solo gl'indirizzi dove devono risiedere ciascuna delle sue istruzioni all'atto dell'esecuzione.
La somma degli n numeri è fatta nell'accumulatore 3, mentre il 2 è usato per contare (scalando) il numero di schede lette e di numeri sommati in 3. Se il contenuto dell'accumulatore 2 è positivo, allora l'istruzione SA>,2,0103 fa saltare a quella contenuta in 0103 per ripetere il ciclo di lettura di un'altra scheda, somma in 3, conteggio in 2.
Allorché il contenuto di 2 è zero non viene più effettuato il salto e si passa all'istruzione seguente, che è uno STOP.
Per l'esecuzione del programma è necessaria una "zona programma" che va dall'indirizzo 100 della memoria all'indirizzo 109 (gli ultimi due registri non contengono istruzioni, ma costanti numeriche per) il programma) e una "zona di lavoro" costituita qui dal solo registro d'indirizzo 150 usato per depositi temporanei di dati.
Per comprendere bene il programma può essere opportuno seguirlo passo a passo, verificando l'effetto dell'esecuzione di ciascuna istruzione. Naturalmente affinchè il programma possa essere eseguito è necessario che il contatore delle istruzioni contenga inizialmente l'indirizzo d'ingresso del programma, cioè 0100, e che il programma stesso sia stato immesso (o, come si dice, "caricato") nella sua zona programma. A ciò si può provvedere o con operazioni manuali o con apposito programma detto "caricatore".
Le istruzioni registrate negl'indirizzi da 0103 a 0106 formano un ciclo che viene ripetuto n volte e che permette di far eseguire molte operazioni simili con poche istruzioni.
Abbiamo perciò visto un esempio di un semplice programma ripetitivo e redatto in modo parametrico rispetto sia agli addendi sia al loro numero.
Vediamo ora succintamente come i programmi possano essere componibili modularmente. Si noti che tale composizione modulare non serve solo a usare più volte uno stesso modulo, ma anche a permettere la redazione contemporanea, da parte di più programmatori, di moduli diversi di uno stesso programma.
Perché vari moduli siano componibili occorre che siano redatti secondo certe norme, variabili da sistema a sistema.
Ciò posto, un modulo può essere inserito in un altro programma o come "sottoprogramma aperto" o come "sottoprogramma chiuso".
Nel primo caso la "zona programma" del modulo da inserire viene appunto inserita nella zona programma dell'altro, tante volte e ovunque sia richiesta l'esecuzione del sottoprogramma aperto, modificando la parte indirizzo delle sue istruzioni come necessario a seconda della zona di memoria in cui vanno inserite.
Nel secondo caso la zona programma del modulo da inserire resta indipendente da quella del modulo in cui avviene l'inserzione, dato che non si ha un'inserzione del testo del sottoprogramma nel testo di un altro programma, ma l'inserzione della sua esecuzione nell'esecuzione dell'altro (fig. 2).
Nel caso d'inserzione dell'esecuzione di un sottoprogramma chiuso si hanno sia istruzioni che fanno saltare dal programma (detto chiamante) al sottoprogramma e che trasmettono a questo gli operandi, sia altre istruzioni che fanno saltare dalla fine del sottoprogramma al punto del programma chiamante da cui si era "chiamato" il sottoprogramma stesso. L'uso di sottoprogrammi chiusi è perciò utile quando essi sono piuttosto lunghi.
In alcuni linguaggi programmativi (v. oltre) l'uso di sottoprogrammi aperti avviene per mezzo di istruzioni apposite, dette "macroistruzioni".
Accenniamo infine alla possibilità di rappresentare schematicamente programmi mediante grafi orientati, detti "diagrammi di flusso", di cui in fig. 3 è dato un esempio rappresentante il programma per la somma di n numeri an,an-1, . . .,a1 prima descritto.
Il grafo ha due nodi, marcati I, F, che rappresentano l'inizio e la fine del programma. Ha poi altri due nodi rettangolari in cui è mostrata l'assegnazione di nuovi valori alle variabili i, s, che corrispondono rispettivamente al contenuto degli accumulatori 2 e 3.
Il significato del segno := nella formula s := s + ai (e nelle altre) è quello di un "operatore di assegnazione" che assegna alla variabile s alla sua sinistra il valore dell'espressione s + ai alla sua destra, cioè somma ai a s. Così, la formula i := i − 1 corrisponde a diminuire di 1 il valore di i.
L'interpretazione del grafo è la seguente. S'inizia dal nodo I e seguendo l'arco orientato uscente da esso si arriva al nodo che assegna a i il valore n e a s il valore 0. Al nodo successivo si somma an al valore attuale di s e si sottrae 1 al valore di i. Il nodo seguente ha forma romboidale e ha due archi uscenti: si seguirà l'arco marcato "sì" se la condizione indicata nel nodo (i > 0) è soddisfatta, altrimenti si segue l'arco marcato "no" e si arriva alla fine. Perciò finché è i > 0 si continuerà a sommare il prossimo numero ai alla somma s dei suoi predecessori e a sottrarre 1 da i.
I diagrammi di flusso hanno il pregio di rappresentare efficacemente programmi in modo abbastanza generale, senza dover tener conto della struttura di un particolare e. e della notazione usata per rappresentarne le istruzioni.
Inoltre, il calcolo di un'espressione complicata può essere schematizzato in un unico nodo rettangolare oppure espanso a sua volta in un diagramma di flusso più dettagliato a seconda del livello di astrazione o di dettaglio desiderato e conseguentemente delle operazioni assunte come primitive.
È comunque da notare la possibilità di rappresentare programmi con diagrammi di flusso in cui si usano essenzialmente solo due tipi di nodi: quello rettangolare corrispondente a operazioni di assegnazione di nuovi valori alle variabili del programma e quello romboidale corrispondente alla selezione fra due possibili operazioni successive.
Quando si vogliono introdurre operazioni relative alle unità periferiche od operazioni di selezione più complesse, si può usare una simbologia più vasta e in gran parte standardizzata anche a livello internazionale.
Linguaggi programmativi. - La tecnologia attuale, imponendo l'uso di dispositivi a due stati, fa sì che qualunque tipo di dato sia rappresentato negli e. con strutture di dati fondate sulle cifre binarie 0 e 1, il che però rende il dato male comprensibile all'uomo.
È però usuale per i programmatori rappresentare i numeri con notazione decimale e, per es., la parte operazione di ciascuna istruzione con un codice letterale facilmente memorizzabile (come è stato fatto nel paragrafo precedente).
Presto però sorge la necessità di parametrizzare i programmi anche rispetto alla zona di memoria in cui operano e, d'altra parte, di rappresentare con codici mnemonici anche la parte indirizzo di un'istruzione o l'indirizzo in cui è memorizzata l'istruzione.
Si comincia così ad avere dei "linguaggi programmativi" che pur essendo riferiti a un particolare tipo di e., permettono di scrivere dei programmi in una notazione più comoda e svincolata dalla parte di memoria o dalle altre risorse (unità periferiche, ecc.) effettivamente disponibili.
Per linguaggio programmativo s'intende un linguaggio, cioè un alfabeto e un insieme di regole per combinarne i caratteri, usato per esprimere programmi.
Un linguaggio programmativo può essere orientato verso un particolare tipo di e. oppure no. Nel primo caso terrà conto della struttura dell'e. e permetterà di fare riferimento alle particolarità delle sue unità e agli organi di questo. È questo il caso dei "linguaggi macchina", che contengono tutte e sole le istruzioni dell'e. (anche se espresse in un codice diverso da quello binario) e dei "linguaggi assemblativi", che contengono non solo delle istruzioni corrispondenti a quelle dell'elaboratore, ma anche altre che permettono un comodo uso dei sottoprogrammi, delle unità periferiche, ecc. Per questi linguaggi, naturalmente, operandi e operazioni saranno quelli corrispondenti alle strutture di dati primitive (v. informatica, in questa App.) dell'e. e perciò: bit, caratteri, parole, numerali in virgola fissa o mobile, e operazioni relative.
Nel caso in cui il linguaggio programmativo sia indipendente da un particolare tipo di e. si cerca di soddisfare varie esigenze, e in particolare le seguenti:
1) Possibilità di redigere dei programmi che, previa traduzione, possono essere eseguiti da un e. di qualunque tipo purché, naturalmente, di potenza adeguata.
2) Disponibilità di strutture di dati (vettori, matrici, archivi di dati, ecc.) non usualmente disponibili come primitive negli e., ma che soddisfano le necessità imposte da classi di problemi usuali (per es., problemi numerici, amministrativi, ecc.) e che possono portare a una facile realizzazione di altre utili strutture di dati.
3) Possibilità di usare notazioni ed espressioni di algebre già note e di avere la rivelazione di errori a livello ortografico e sintattico e qualche aiuto per la verifica della correttezza di programmi e di operandi.
Tali linguaggi sono detti linguaggi ad alto livello, in quanto operano a un livello di maggiore astrazione e di minore dettaglio dei linguaggi macchina. Essi possono a loro volta classificarsi in: "linguaggi procedurali" se orientati verso l'espressione di particolari classi di procedimenti (numerici, amministrativi, ecc.); "linguaggi orientati verso i problemi" se sono particolarmente adatti alla descrizione di classi di problemi piuttosto che verso le procedure per la loro soluzione; "linguaggi di descrizione e di simulazione" se particolarmente adatti a descrivere dei sistemi o a simularne il comportamento.
La possibilità di far eseguire da un certo e. programmi scritti in linguaggi diversi da quelli macchina è condizionata dalla disponibilità di altri programmi, detti compilatori, i quali traducono i programmi in linguaggio ad alto livello nel linguaggio macchina dell'e. a disposizione o in linguaggio assemblativo e inoltre provvedono a diagnosticare eventuali errori a livello ortografico e sintattico.
Più oltre tratteremo brevemente dei compilatori e degli altri programmi analoghi che aiutano il programmatore nell'uso dei vari linguaggi programmativi mentre qui vogliamo dare alcuni cenni sui tipi più comuni di istruzioni dei linguaggi ad alto livello, con particolare riguardo a quelli procedurali.
Innanzi tutto precisiamo che agli operandi che non siano delle costanti ma delle variabili, si fa riferimento mediante identificatori o nomi e che le istruzioni si dividono in genere in due tipi: descrittive (o dichiarative) e imperative (od operative). Le prime descrivono il tipo di dato identificato da un certo nome (per es., numero intero, vettore, ecc.) cioè il dominio di ciascuna variabile, o, addirittura, una struttura di dati (cioè un dominio e un insieme di operazioni), un sottoprogramma, ecc.
Le istruzioni operative assegnano valori a tali variabili mediante istruzioni di assegnazione semplice o mediante istruzioni composte.
Le prime corrispondono alle operazioni di assegnazione di cui abbiamo trattato a proposito dei diagrammi di flusso e seguono lo schema V := E, dove V è una variabile relativa a una certa struttura di dati ed E è un'espressione formata con costanti, variabili e operazioni di quella struttura.
Istruzioni composte corrispondono alla "concatenazione" di più istruzioni semplici, alle istruzioni "condizionali" e a quelle "iterative" schematicamente rappresentate nella fig. 4 sia in forma di diagrammi di flusso sia in notazione inglese. In tale figura, C è una condizione (corrispondente a un predicato) mentre I, I1, I2, . . ., In sono istruzioni di assegnazione semplici o composte.
Istruzioni particolari sono quelle relative alle unità periferiche, quelle di salto, di definizione e di chiamata di sottoprogramma.
Per ulteriori notizie rimandiamo alla bibliografia, facendo però presente che i linguaggi macchina e quelli orientati verso la macchina sono descritti solo dai manuali delle case costruttrici degli e., a parte qualche eccezione per i più diffusi.
Corredi programmativi e sistemi operativi. - Abbiamo già visto che un e. dev'essere dotato di vari programmi che operano su altri programmi traducendoli o caricandoli in memoria. Cerchiamo ora di passare in rapida rassegna ciò che comunemente viene chiamato il "corredo programmativo" (in ingl. software, per contrasto con hardware, cioè le apparecchiature) e che può considerarsi diviso in raccolta di programmi applicativi (cioè per particolari applicazioni) e sistema operativo.
Il sistema operativo è un insieme integrato di programmi di servizio il cui fine è di rendere più agevole l'uso specifico e l'esercizio di un impianto di elaborazione dati e dei suoi programmi applicativi. Il sistema operativo di un elaboratore può considerarsi composto dai seguenti programmi o sistemi di programmi:
1) Compilatori, che traducono programmi scritti in linguaggi ad alto livello in programmi scritti in linguaggio macchina o in linguaggio assemblativo, eseguendo anche dei controlli sulla correttezza dei programmi dal punto di vista ortografico e sintattico. Alcuni compilatori eseguono tali controlli istruzione per istruzione (il linguaggio, però, deve avere caratteristiche particolari) e perciò permettono un intervento immediato del programmatore in caso di errori o ripensamenti. Tali compilatori sono detti interattivi.
2) Interpreti, che consentono di tradurre e interpretare (cioè eseguire) un programma istruzione per istruzione e perciò permettono un'interazione del programmatore in fase di esecuzione per vari scopi (diagnosi di errori, simulazione di altri e., ecc.). Tracciatori sono degl'interpreti che stampano il contenuto di alcuni registri significativi per consentire di seguire il processo di esecuzione del programma.
3) Assemblatore, che traduce programmi scritti in linguaggio assemblativo in programmi scritti in linguaggio macchina e "rilocabili", cioè strutturati in modo da poter essere facilmente modificati per occupare una qualunque zona della memoria. Un collegatore può modificare più moduli rilocabili in un unico programma, anch'esso rilocabile, che occupa un'unica zona di memoria. Un caricatore può modificare a sua volta un programma per caricarlo in una certa zona di memoria e avviarne l'esecuzione.
4) Programmi per gestire archivi di altri programmi o di operandi su memorie secondarie. Un "archivio" è un insieme sistematico di dati (accessibili in base a un nome o in base alla loro posizione) su memoria secondaria.
5) Nei sistemi più semplici un monitore e in quelli più complessi un supervisore, che gestiscono l'uso delle varie parti dell'e. e del suo corredo di programmi, in base alle richieste di servizio, alle unità disponibili e a criteri di gestione ottimale.
Un supervisore può essere composto da decine di migliaia di istruzioni quando deve, per es., gestire un e. che funziona in multiprogrammazione, cioè che alterna l'esecuzione di parti di programmi diversi e mutuamente indipendenti allo scopo di ottimizzare lo sfruttamento delle varie unità dell'e., sia pure gestendo i lavori da fare secondo un sistema di priorità, che in genere favorisce i lavori più brevi.
L'alternanza dell'esecuzione di programmi diversi da parte del governo è opportuna, fra l'altro, perché quando un certo programma avvia un'operazione di un'unità periferica, questa può avvenire indipendentemente dal governo e dall'unità aritmetica e logica. Queste, potendo compiere decine di migliaia di operazioni prima che l'operazione sull'unità periferica sia finita, possono essere messe nel frattempo a disposizione per l'esecuzione di altri programmi.
La sincronizzazione delle varie operazioni è resa possibile da un insieme di segnali detti "d'interruzione" che vengono inviati al governo dalle unità periferiche quando esse finiscono un'operazione. Segnali d'interruzione vengono anche generati in corrispondenza a fatti anomali, quali per es. la rivelazione di un errore in un'unità.
L'invio dei segnali suddetti provoca la sospensione dell'esecuzione dei programmi ordinari e l'entrata in azione del supervisore.
Impianti di elaborazione. - Un impianto di elaborazione di dati è costituito da uno o più e. e dalle macchine e apparati per la preparazione e la verifica dei supporti di dati (schede, nastri, dischi) per l'ingresso degli operandi, dalle macchine per la manipolazione dei supporti di dati usciti dagli e. con i risultati delle elaborazioni (quali scarbonatrici, separatrici, imbustatrici, ecc. per togliere l'eventuale carta carbone, per separare i moduli stampati, per imbustarli, ecc.) e da apparati ausiliari (di condizionamento, di alimentazione, ecc.).
Gli e. dell'impianto possono essere collegati fra loro (ed eventualmente sostituirsi vicendevolmente e automaticamente in caso di emergenza) oppure possono essere totalmente indipendenti e trovarsi in uno stesso centro per comodità d'uso e di gestione.
La collocazione dei macchinari deve tener conto dei movimenti dei supporti di dati, che possono raggiungere volumi notevolissimi: un lettore di schede può leggere comunemente a velocità di 500 ÷ 1000 schede al minuto e una stampante può stampare altrettante righe nello stesso tempo. Stampanti speciali possono superare le 10.000 righe al minuto.
Anche il lavoro di montaggio e smontaggio manuale di bobine di nastro e di pacchi di dischi dev'essere accuratamente pianificato e controllato.
Negli ultimi anni l'uso di sistemi operativi opportuni e di terminali adatti all'uso interattivo (telescriventi apposite, terminali video su cui far apparire decine di linee di testo, ecc.) hanno permesso l'interrogazione diretta delle memorie degli e. e lo svolgimento interattivo di semplici elaborazioni.
Sono ormai familiari i terminali di prenotazione delle ferrovie o delle linee aeree o quelli in uso nelle banche per le operazioni sui conti correnti.
In questo modo i terminali di un impianto di elaborazione non sono più confinati nel centro di elaborazione, ma sono distribuiti, per es., in tutto un palazzo per uffici, in tutta un'area cittadina (caso di un impianto per l'automazione di un'anagrafe comunale) sul territorio nazionale (caso delle prenotazioni ferroviarie) o su gran parte del mondo (caso delle prenotazioni aeree).
I terminali possono essere collegati a un impianto centrale direttamente oppure attraverso piccoli e., che agiscono come concentratori per migliorare l'utilizzazione delle linee di comunicazione e per altri compiti relativamente semplici.
L'insieme assume così una configurazione a raggera, con il grosso della capacità di elaborazione nel centro e con un'interazione continua fra centro e periferia. Con questa configurazione si ha la possibilità di aumentare la capacità di memorizzazione e di elaborazione dei concentratori diminuendo quella del centro.
Un altro tipo di configurazione per sistemi formati da vari e. collegati fra loro con linee di comunicazioni più o meno lunghe, è quello a maglie, in cui si hanno vari centri di elaborazione collegati fra loro da una rete non stellare, ma generica.
Notiamo infine che tali reti possono avere anche dimensioni fisiche modeste ed essere, per es., costituite da un insieme di minicalcolatori di uno stesso ufficio collegati fra loro.
Il problema delle reti di e. pone naturalmente problemi particolari ai sistemi operativi.
Applicazioni e diffusione degli elaboratori. - È da osservare che le applicazioni che più colpiscono l'attenzione del pubblico (guida di satelliti, controllo diretto di degenti in gravi condizioni, gioco degli scacchi, istruzione assistita dal calcolatore, ecc.) sono spesso anche le meno usuali.
Le applicazioni più usuali riguardano, nell'ordine, l'industria manufatturiera (meccanica, chimica, tessile, alimentare, ecc.), la finanza, il commercio, la pubblica amministrazione, e perciò riguardano applicazioni di tipo gestionale e amministrativo: contabilità del personale, di magazzino, di clienti e fornitori, gestione degli ordini, programmazione e controllo della produzione, gestione dei conti correnti, dei depositi a risparmio, del portafoglio, amministrazione di titoli, ecc.
Per questo tipo di applicazioni il linguaggio più usato è il Cobol e, in percentuale molto minore, il linguaggio assemblativo.
Le applicazioni tecniche e scientifiche rientrano in gran parte nelle seguenti categorie: calcoli numerici in genere (per cui i linguaggi più usati sono il Fortran e in misura assai minore l'Algol), il controllo di impianti o di esperimenti di laboratorio (che richiedono il più delle volte la generazione di sistemi operativi ad hoc), la modellistica e la simulazione (per cui si hanno linguaggi specializzati), la progettazione (per cui esistono dei sistemi di programmi particolari per alcuni settori operativi), il controllo delle macchine utensili (per cui anche esistono linguaggi particolari), il controllo dell'esecuzione di grandi progetti (per cui esistono sistemi di programmi facenti uso di procedure tipo Pert e simili), ecc.
È però da rilevare che diverse applicazioni tecniche (controllo di impianti, di progetti, ecc.) hanno dei forti legami con le applicazioni gestionali, le quali, d'altronde, affrontano problemi di modellistica e di simulazioni aziendali simili a quelli affrontati nelle applicazioni tecniche.
Altra categoria di applicazioni d'interesse notevole e che investe vari campi è quella della "documentazione", cioè della memorizzazione di testi e del loro reperimento in base al loro contenuto. Ciò non ha applicazioni solo nelle bibloteche, ma anche nell'amministrazione, in giurisprudenza, ecc.
Per quanto riguarda la diffusione degli e. è da notare che alla fine del 1974 in Italia se ne avevano 5750 (con un incremento del 12% rispetto all'anno precedente), che in valore di fitto annuo corrispondevano a circa 450 miliardi di lire di allora (si noti che il prezzo di un e. corrisponde a 4 ÷ 5 volte il suo fitto annuo). Tenendo conto delle spese per la programmazione e la gestione, delle spese per il personale, ecc., la spesa annua corrispondente supera abbondantemente i mille miliardi.
Corrispondentemente, alla fine del 1974 gli e. installati nella Repubblica Federale di Germania superavano i 20.000, con un incremento annuo del 13% (studio Diebold).
È importante notare che nel 1965 risultavano installati in Italia 850 e. contro 1800 in Germania, perciò il rapporto del numero di e. installati nei due paesi è passato in 10 anni da 2,1 a 3,5 circa, mostrando come il divario fra i due paesi vada rapidamente aumentando, per non parlare del divario con gli SUA o il Giappone.
I dati suddetti non comprendono i minicalcolatori, i microcalcolatori, i calcolatori tascabili e quelli da tavolo (che ormai si diffondono in tutti gli ambienti, anche per la loro capacità di eseguire direttamente programmi in linguaggi ad alto livello come il Basic) e i vari terminali, dotati di possibilità più o meno ampie di programmazione autonoma.
Bibl.: P. Wegner, Programming languages, information structure and machine organization, New York e Londra 1968; M. A. Joslyn, Computer selection, Reading, Mass., 1968; F. Ph. Brooks, K. E. Iverson, Automatic data processing, New York 1969; D. Gries, Compiler construction for digital computers, ivi 1971; V. Falzone, E. Costantini, Elaboratori elettronici e tecnica della programmazione in Fortran e Algol, Milano 1971; A. F. Cardenas e altri, Computer science, New York 1972; H. Stone, Introduction to computer organization and data structures, New York e Londra 1972; G. Perotti, Calcolatori elettronici, Torino 1972; G. Weinberg e altri, Structured programming in PL/C, New York 1973; D. Knuth, The art of computer programming, 3 voll., Reading, Mass., 1968-71-74; A. Siciliano, Cobol, Bologna 1972; A. Frisiani, Calcolatori elettronici. Introduzione alla teoria delle reti logiche, Milano 1972; F. Hill, G. R. Peterson, Digital system hardware organization and design, New York 1973; N. Wirth, Systematic programming, an introduction, New York e Londra 1973; P. Brinch Hansen, Operating system principles, Londra 1973.