Discussione come fa un linguaggio di programmazione a farsi capire dalla macchina?

Stato
Discussione chiusa ad ulteriori risposte.

nomepiueasy

Utente Gold
17 Gennaio 2018
320
96
67
230
come da titolo

ho capito che il linguaggio è una "semplificazione" per poter comunicare con la macchina, in quanto esso dopodichè verrà tradotto in un linguaggio comprensibile alla macchina , ovvero acceso e spento, ma il punto è come fa questo linguaggio primario a farsi capire dalla macchina stessa
allegatemi pure fonti in inglese se necessario

grazie ^^
 
Il linguaggio macchina è sostanzialmente una traduzione in binario del linguaggio assembly. Di conseguenza, come probabilmente già sai, l'assembly non è un linguaggio di programmazione vero e proprio, ma una famiglia di linguaggi di programmazione: l'assembly dei processori x86_64 (eg. il tuo computer) è diverso dall'assembly degli ARM (eg. il tuo smartphone), ma rimangono molto simili in quanto sono entrambi delle traduzioni da stringhe binarie (0 e 1) a caratteri ASCII (A-Z, 0-9 e qualche simbolo).
Nel momento in cui viene progettata una CPU (o meglio, un'architettura) si definisce l'ISA (Instruction Set Architettcture), ovvero quali sono quali sono le istruzioni che il processore andrà ad eseguire (somma, moltiplicazione, ecc...) e come funzionano (dimensione dei registri, indirizzamento della memoria, ecc...). Nel momento in cui si progetta un'ISA ci sono principalmente due strade che si possono prendere: RISC (Reduced Instruction Set Computer) oppure CISC(Complex Instruction Set Computer). Le architetture RISC (eg. l'ARM che hai nello smartphone) si basano sul definire solo solo poche istruzioni (poche decine) e di effettuare le operazioni più complesse a livello software, con la composizione di queste poche e semplici istruzioni, mentre le architetture CISC (eg. l'x86_64 che hai nel pc) tendono a definire molte istruzioni (diverse centinaia) che generalmente fanno cose anche abbastanza complesse. La sostanza di questo discorso è che non è necessario avere tante istruzioni: con qualche decina di comandi assembly riesci a fare tutti i programmi che vuoi, esiste anche un caso limite (praticamente inutilizzato) dove usando soltanto un'istruzione si riesce a fare tutto.

Ogni istruzione in linguaggio macchina è identificata da un codice operativo (OP Code), ovvero parte della stringa binaria che forma l'istruzione serve per "dare un nome" all'istruzione. Per esempio, se tutte le istruzioni hanno una lunghezza prefissata di 32 bit, chi progetta l'ISA può scegliere che i primi 4 bit servono per identificare l'istruzione: quindi potrebbe dire che le istruzioni che iniziano per 0000 sono le addizioni, quelle che iniziano per 0001 sono le sottrazioni, quelle che iniziano per 0010 sono le moltiplicazioni, ecc... Se un codice operativo è formato da n bit, avremo 2^n possibili op codes.
Gli altri bit che formano un'istruzione hanno un significato dipendente dall'operazione stessa: ad esempio, se voglio prelevare un valore dalla memoria centrale (RAM) gli altri bit potrebbero servirmi per scegliere l'indirizzo del dato in questione; mentre se voglio effettuare un'addizione tra registri (registroA = registroB + registroC), gli altri bit potrebbero servirmi per "dare un nome" ai registri.

Nel momento in cui un processore è in funzione, il suo lavoro può essere diviso principalmente in queste fasi: prelevare la prossima istruzione dalla memoria, capire di che istruzione si tratta (guardando l'op code) ed eseguire tale operazione. L'esecuzione di queste fasi viene chiamata fetch-decode-execute cycle. Per eseguire queste fasi il processore usa, in grandissima quantità, un componente elettronico chiamato transistor. A mo' di Lego, questi transistor vanno a formare le porte logiche, dei dispositivi che permettono di effettuare le operazioni logiche (and, or, not, xor, ecc...) e che a loro volta si compongono per formare circuiti più complessi (multiplexers, flip-flop, ecc...); questi circuiti più complessi formano circuiti ancora più complessi (shift registers, ALU, ecc...) e così via fino ad avere un sistema (la CPU) in grado di effetturare il fetch-decode-execute cycle che ti ho brevemente descritto in precedenza.

Tra questi componenti, possiamo dire che il transistor sia l'unico che vede il segnale elettrico definito dalla differenza di potenziale (i volt). Dalle porte logiche in poi non si parla più di quanti volt ci sono su un certo connettore, ma si parla di stati. Gli input e gli output di una porta logica sono degli stati e questi stati possono essere vero (1) oppure falso (0). Avere lo stato vero piuttosto che lo stato falso è giustificato dalla differenza di potenziale (volt) tra i due connettori: se c'è un cambiamento sufficiente a far "scattare" il transistor, c'è un cambiamento di stato.
 
Il linguaggio macchina è sostanzialmente una traduzione in binario del linguaggio assembly. Di conseguenza, come probabilmente già sai, l'assembly non è un linguaggio di programmazione vero e proprio, ma una famiglia di linguaggi di programmazione: l'assembly dei processori x86_64 (eg. il tuo computer) è diverso dall'assembly degli ARM (eg. il tuo smartphone), ma rimangono molto simili in quanto sono entrambi delle traduzioni da stringhe binarie (0 e 1) a caratteri ASCII (A-Z, 0-9 e qualche simbolo).
Nel momento in cui viene progettata una CPU (o meglio, un'architettura) si definisce l'ISA (Instruction Set Architettcture), ovvero quali sono quali sono le istruzioni che il processore andrà ad eseguire (somma, moltiplicazione, ecc...) e come funzionano (dimensione dei registri, indirizzamento della memoria, ecc...). Nel momento in cui si progetta un'ISA ci sono principalmente due strade che si possono prendere: RISC (Reduced Instruction Set Computer) oppure CISC(Complex Instruction Set Computer). Le architetture RISC (eg. l'ARM che hai nello smartphone) si basano sul definire solo solo poche istruzioni (poche decine) e di effettuare le operazioni più complesse a livello software, con la composizione di queste poche e semplici istruzioni, mentre le architetture CISC (eg. l'x86_64 che hai nel pc) tendono a definire molte istruzioni (diverse centinaia) che generalmente fanno cose anche abbastanza complesse. La sostanza di questo discorso è che non è necessario avere tante istruzioni: con qualche decina di comandi assembly riesci a fare tutti i programmi che vuoi, esiste anche un caso limite (praticamente inutilizzato) dove usando soltanto un'istruzione si riesce a fare tutto.

Ogni istruzione in linguaggio macchina è identificata da un codice operativo (OP Code), ovvero parte della stringa binaria che forma l'istruzione serve per "dare un nome" all'istruzione. Per esempio, se tutte le istruzioni hanno una lunghezza prefissata di 32 bit, chi progetta l'ISA può scegliere che i primi 4 bit servono per identificare l'istruzione: quindi potrebbe dire che le istruzioni che iniziano per 0000 sono le addizioni, quelle che iniziano per 0001 sono le sottrazioni, quelle che iniziano per 0010 sono le moltiplicazioni, ecc... Se un codice operativo è formato da n bit, avremo 2^n possibili op codes.
Gli altri bit che formano un'istruzione hanno un significato dipendente dall'operazione stessa: ad esempio, se voglio prelevare un valore dalla memoria centrale (RAM) gli altri bit potrebbero servirmi per scegliere l'indirizzo del dato in questione; mentre se voglio effettuare un'addizione tra registri (registroA = registroB + registroC), gli altri bit potrebbero servirmi per "dare un nome" ai registri.

Nel momento in cui un processore è in funzione, il suo lavoro può essere diviso principalmente in queste fasi: prelevare la prossima istruzione dalla memoria, capire di che istruzione si tratta (guardando l'op code) ed eseguire tale operazione. L'esecuzione di queste fasi viene chiamata fetch-decode-execute cycle. Per eseguire queste fasi il processore usa, in grandissima quantità, un componente elettronico chiamato transistor. A mo' di Lego, questi transistor vanno a formare le porte logiche, dei dispositivi che permettono di effettuare le operazioni logiche (and, or, not, xor, ecc...) e che a loro volta si compongono per formare circuiti più complessi (multiplexers, flip-flop, ecc...); questi circuiti più complessi formano circuiti ancora più complessi (shift registers, ALU, ecc...) e così via fino ad avere un sistema (la CPU) in grado di effetturare il fetch-decode-execute cycle che ti ho brevemente descritto in precedenza.

Tra questi componenti, possiamo dire che il transistor sia l'unico che vede il segnale elettrico definito dalla differenza di potenziale (i volt). Dalle porte logiche in poi non si parla più di quanti volt ci sono su un certo connettore, ma si parla di stati. Gli input e gli output di una porta logica sono degli stati e questi stati possono essere vero (1) oppure falso (0). Avere lo stato vero piuttosto che lo stato falso è giustificato dalla differenza di potenziale (volt) tra i due connettori: se c'è un cambiamento sufficiente a far "scattare" il transistor, c'è un cambiamento di stato.
allora la domanda funge spontanea, come può un pezzo di silicio a capire ed eseguire le istruzioni?
 
allora la domanda funge spontanea, come può un pezzo di silicio a capire ed eseguire le istruzioni?
Lo fa nella fase di decode, che serve per capire qual'è l'istruzione corrente. Guardando l'opcode, un multiplexer* sceglie che circuiti logici attivare/disattivare nella fase di execute e, in base a quelli, viene eseguita l'operazione desiderata. Come ti ho scritto nel messaggio precedente, l'opcode è sostanzialmente il nome dell'istruzione. Per ricapitolare:
  • fase di fetch: prelevo l'istruzione corrente dalla memoria;
  • fase di decode: leggo l'opcode dell'istruzione corrente e scelgo che circuiti attivare/disattivare (capisco cosa devo fare);
  • fase di execute: eseguo l'istruzione.
Un'istruzione è una stringa binaria che nelle architetture RISC ha una lunghezza prefissata (eg. 32 bit). Il singolo 1 e 0 è dato dallo stato di uscita di una porta logica che varia in base al cambiamento di differenza di potenziale sui pin di un transistor.

*La fase di decode non è particolarmente complessa, ma ridurla a uno stupidissimo multiplexer è chiaramente un'over-semplificazione per farti capire il concetto: in base a cosa leggo scelgo cosa attivare (eg. leggo l'opcode 101011, quindi attivo i circuiti che fanno la somma tra registri).


Io non ho mai parlato di pezzi di silicio, ho parlato di transistors, porte logiche, flip-flop, registri, ecc... Se vogliamo parlare di "pezzi di silicio" dobbiamo semplicemente spezzare ancora di più il Lego che stiamo utilizzando per costruire la nostra CPU. Per come te l'ho detta io la mattonella di base è il transistor, ma che cos'è il transistor? Un semiconduttore composto da silicio il cui comportamento è dettato da eventi fisici che non sono in grado di spiegarti. Ma non penso che tutta la menata delle giunzioni drogate NPN / PNP sia di tuo interesse.

Per come la vedo io possiamo semplificare il discorso dicendo: col silicio construiamo il transistor, col transistor costruiamo la porta logica, con la porta logica costruiamo multiplexers, flip-flops e cose di questo tipo e con questi costruiamo i registri (unione di più flip-flop), le ALU (multiplexer + porte logiche) e cose di questo tipo che usiamo infine per effettuare quello che molto schematicamente viene chiamato fetch-decode-execute cycle, che caratterizza le CPU.
Un'istruzione è una stringa binaria, questa stringa binaria è memorizzata in un registro, questo registro è formato da un mucchio di flip-flop, questi flip-flop sono formati da porte logiche e queste porte logiche sono formate da transistor. Ogni transistor ha uno stato vero/falso (1/0) che è dettato dal cambiamento di differenza di potenziale sui suoi pin.
Prendo l'istruzione (una stringa binaria, diciamo di lunghezza prefissata, anche se non è detto) e tramite questi circuiti logici leggo il suo codice operativo (eg. 101011 => è una ADD) che mi indica che utilità hanno i bit che la compongono (eg. sto indicando i 3 registri per fare A = B + C). Dopodiché si tratta solamente di indirizzare i bit verso i circuiti logici che svolgono l'operazione desiderata (a grandissime linee: un multiplexer).
 
Ultima modifica:
Ti sintetizzo la parte dei transistor dato che l'esame di Fisica in cui c'era un accenno l'ho superato 2 settimane fa! Iniziavo a credere fosse stato inutile saperla, poichè la prof l'aveva preferita a discapito della Relatività che preferivo, evidentemente mi sbagliavo.

La caratteristica principale per il quale un transistor funziona è che a causa della sua struttura atomica si riesce a realizzare facilmente(quindi con piccole correnti) uno stato di switching on/off per la quale poi entra in gioco tutto ciò che ti ha spiegato St3ve.
In sintesi la struttura atomica è basata su un principio fisico dovuto tra un elemento base come silicio (con 4 elettroni di valenza) e con un elemento di drogaggio (es arsenico, fosforo o vanadio con 5 elettroni di valenza) che legandosi tra di loro hanno in tutto 1 elettrone in eccesso che è legato soltanto da una attrazione coulombiana(molto più debole di quella chimica). Questo "eccesso" è facilmente distaccabile con una semplice agitazione termica(che può essere a temperatura ambiente). Questo elettrone quindi è libero di spostarsi, proprio come succedde agli elettroni nei materiali conduttori. D'altra parte se si effettua un drogaggio con un elemento trivalente( 3 elettroni di valenza) si crea una "lacuna", che cercherà di attirare un elettrone adiacente che si è svincolato per agitazione termica. Unendo questi due stati in 2 zone ben distinte si crea quella che si chiama Giunzione p - n (p fa riferimento alle lacune, quindi cariche positive, n agli eccessi perciò cariche negative). Se si crea un circuto tra queste zone e si applica una differenza di potenziale ai capi con positivo nella zona p e negativo nella zona n si riesce a polarizzare direttamente il sistema, permettendo quindi la generazione di correnti molto alte anche con d.d.p basse. Se si invertono i poli di alimentazione si avrà una polarizzazione inversa dove non avviene il passaggio di corrente(ti risparmio il discorso sui campi elettrici che entrano in gioco poichè sennò diventa troppo lungo il discorso). A questo punto entrano in gioco i transistor; non sono altro che una doppia giunzione accennata poco fa: P - N - P oppure N - P - N
Quindi un transistor semplice ha 3 zone ben distinte chiamate emettitore (A), base (B), collettore (C) e lo stato on/off è determinato da come vengono applicate le tensioni tra A-B e B-C:
  • Ti trovi una corrente molto alta(sempre con tensioni molto basse) alla base con tensioni uguali applicate
  • Ti trovi una corrente nulla alla base con tensioni opposte

Anche qui ti risparmio il discorso su come lacune/eccessi giocano un ruolo importante e come interagiscono poichè diventerebbe troppo lungo senza contare che ci sono molti tipi di transistor (mos-fet, bjt, hbt...) ognuno con caretteristiche particolari.
A questo punto una volta che si riesce a distinguere 0/1 si possono sfruttare i transistor per fare circuiti integrati e dopo entra in gioco la parte di St3ve: ad esempio i registri puoi immaginarli come tanti flip-flop che vengono controllati dallo stesso clock. Puoi farti anche tu una tua alu a 1bit che ti permette di fare somma, sottrazione, and logico e or logico componendo i vari adder e sfruttando i multiplexer. Più aumentano i transistor più avrai capacità di processamento del circuito integrato, il numero dei transistor è dettato dalla legge di Moore. Bisognerebbe fare un altro discorso a parte su quali sono i limiti dei circuiti, cpu e il problema dello stampaggio dei circuiti su schede, ma ci spostiamo troppo dall'argomento.


Il discorso appena fatto è chiaramente semplificato e spiega a grandi linee per darti un idea. L'Informatica quindi esiste grazie alla Fisica(come la maggior parte di tutto il mondo che ci circonda), tutte le risposte di come funzionano le cose basilarmente le trovi li
 
  • Mi piace
Reazioni: nomepiueasy
Puoi ricercare su google cercando parole chiavi prendendole dal mio post e quello di steve, io ho trovato questo che può essere utile
Chiaramente tutto in inglese devi ricercare se vuoi qualcosa di interessante
/ot bel sito, conosci qualcosa di simile anche per altre materie? (mi vanno bene qualsiati)
 
Stato
Discussione chiusa ad ulteriori risposte.