Come si passa esattamente dai set di istruzioni binarie / esadecimali a quelli di assemblaggio?


13

Quindi ho cercato di imparare un po 'di programmazione Embedded / Assembly per un po' qui di recente, oltre a cercare di imparare il livello più basso (gate e simili).

Una cosa però mi confonde .... è come "ottenere" set di istruzioni. Capisco un po 'come funzionano cancelli / TTL e simili, ma non vedo come si passa da quello a mov, aggiungere, clr ecc ...?

Probabilmente è una domanda stupida ... ma voglio dire ripenso ai primi microprocessori / controller e penso ... come hanno esattamente progettato un set di istruzioni e farlo funzionare?

modifica: suppongo Clarity, fingo di parlare del primo microprocessore, come sono passati dal binario alla creazione di un set di istruzioni?


2
Ogni istruzione ha un valore, il compilatore converte il codice in queste istruzioni, in base alla struttura del codice.
Ramhound,

1
Non sono sicuro di aver compreso perfettamente la tua domanda, ma penso che puoi trovare la tua risposta qui , qui o qui .
e-MEE,


3
come sono passati dal binario alla creazione di un set di istruzioni? In realtà "loro" no - è il contrario, almeno in generale. I progettisti della CPU determinano le operazioni che la CPU eseguirà, quindi creano il set di istruzioni da quello e quindi associano le istruzioni (mnemoniche) ai codici operativi (codice binario della macchina). @Scott Whitlock ha fornito una buona risposta di seguito, volevo solo affrontare l'ultima parte della tua domanda perché il tuo presupposto, almeno nella mia esperienza, è arretrato.
Radian,

1
Questo libro davvero carino: www1.idc.ac.il/tecs è ciò che mi ha spiegato tutto, la maggior parte dei capitoli sono disponibili gratuitamente online. Progetti il ​​tuo chip (in un semplice linguaggio descrittivo hardware) da nand gates, quindi un assemblatore quindi un compilatore, quindi scrivi un sistema operativo nella lingua che hai creato! Roba incredibile, e come qualcuno senza una laurea in scienze era tempo ben speso per me!
bplus,

Risposte:


18

Il cuore di una CPU è l' ALU . È responsabile di prendere un'istruzione (come MOV) che è solo alcune serie predefinite di cifre binarie, e anche di prendere 0, 1 o 2 operandi e di eseguire l'operazione applicabile su di essi. L'istruzione più semplice potrebbe essere un NOP (nessuna operazione) che sostanzialmente non fa nulla. Un'altra operazione tipica è AGGIUNGI (aggiunge due valori).

L'ALU legge e scrive i dati da e verso i "registri". Queste sono piccole posizioni di memoria interne alla CPU. Parte dell'istruzione (da 2 a 3 bit per ciascun ingresso in base al numero di registri disponibili) indica da quale registro leggere. Esistono unità nella CPU esterne all'ALU che gestiscono il caricamento dei dati richiesti (e le istruzioni) dalla memoria nei registri e la scrittura del risultato dai registri nella memoria. Anche la posizione in cui scrivere il risultato verrà codificata in altri 2 o 3 bit.

La scelta di "codici op", che è il numero binario che rappresenta un'operazione, non è arbitraria. I codici operativi ben scelti riducono la complessità della ALU. Ogni bit o gruppo di bit tende ad abilitare e disabilitare determinati gate logici nella ALU. Ad esempio, un'istruzione ADD dovrebbe consentire allo stadio di output di scegliere il risultato della logica di aggiunta interna. Allo stesso modo, un'istruzione MUL sceglierebbe il risultato della logica moltiplicata. A seconda del progetto, è molto probabile che entrambi i circuiti sommatore e moltiplicano eseguano effettivamente le loro operazioni sugli operandi di input, ed è solo la selezione di output (ciò che viene scritto nei bit di output dell'ALU) che cambia.


1
Immagino cosa sto chiedendo, come scelgono? E come possono effettivamente assegnarlo?

1
@Sauron: rileggi nuovamente il terzo paragrafo e cerca di capire l'aritmetica binaria e i circuiti digitali. Posso rappresentare un set di istruzioni con 256 istruzioni da una linea a 8 bit in un circuito digitale. Ciò significa che ho bisogno di 8 porte io sui miei dispositivi hardware per trasferire ogni stato possibile (2 stati per riga ^ 8 linee = 256 possibili stati). L'unità di elaborazione può quindi decidere cosa fare con quel segnale di ingresso digitale. Un circuito digitale significa che hai due stati hardware: Hi e Lo, tensione o nessuna tensione. Ecco da dove proviene il binario. La rappresentazione binaria è quella più vicina al metallo.
Falcon,

3
@Sauron: cerca i multiplexer digitali per vedere come un circuito digitale può scegliere tra uno dei diversi valori. Se hai un bus a 8 bit, hai solo bisogno di 8 di questi multiplexer digitali binari in parallelo.
Scott Whitlock,

1
@Falcon Ok ....... Penso che abbia più senso. Continuo a dimenticare che alla fine tutto si riduce a segnali binari .... e persino un'istruzione come "mov" è ancora rappresentata come binaria.

1
@Sauron - Fai qualche ricerca sulla CPU, ti aiuterà a capire quali sono i codici op e come funzionano. Perché determinati codici operativi siano scelti non è importante, anche fare la domanda "perché" non ha molto senso. Capire come vengono scelti potrebbe aiutarti a capire meglio la CPU e la sua struttura.
Ramhound,

9

Prenderò la tua domanda alla lettera e discuterò principalmente di microprocessori, non di computer in generale.

Tutti i computer hanno una sorta di codice macchina. Un'istruzione è composta da un codice operativo e uno o più operandi. Ad esempio, l'istruzione ADD per Intel 4004 (il primo microprocessore) è stata codificata come 1000RRRR dove 1000 è il codice operativo per ADD e RRRR rappresentava un numero di registro 0-15 (utilizzo1111 in binario).

Tutte le altre istruzioni che fanno riferimento a uno dei 16 registri a 4 bit (come INC, ISZ, LD, SUB, XCHG) usano anche i 4 bit bassi per codificare il numero di registro e varie codifiche dei primi 4 bit per specificare il codice operativo. Ad esempio, ADD, SUB, LD e XCHG utilizzano i codici operativi 1000, 1001, 1010 e 1011 (tutti in binario) combinati con il campo del registro. Quindi puoi vedere come viene utilizzato un modello per semplificare la logica.

I primissimi programmi per computer sono stati scritti a mano, codificando a mano l'1 e lo 0 per creare un programma in linguaggio macchina. Questo è stato quindi programmato in una ROM (memoria di sola lettura). Ora i programmi vengono generalmente scritti nella memoria Flash cancellabile elettricamente, nel caso di microcontrollori, oppure esauriscono la RAM, se i microprocessori. (Quest'ultimo ha ancora bisogno di una sorta di memoria di sola lettura per l'avvio.)

Il linguaggio macchina diventa noioso molto velocemente, quindi sono stati sviluppati programmi assembler che prendono un linguaggio assemblatore mnemonico e lo traducono, di solito una riga di codice assembly per istruzione, in codice macchina. Quindi invece di 10000001, si scriverebbe ADD R1.

Ma il primo assemblatore doveva essere scritto in codice macchina. Quindi potrebbe essere riscritto nel proprio codice assembler e la versione in linguaggio macchina lo utilizzava per la prima volta. Successivamente, il programma potrebbe assemblare se stesso (questo si chiama bootstrap).

Dal momento che il primo microprocessore è stato sviluppato molto tempo dopo la presenza di mainframe e minicomputer e il 4004 non era comunque adatto all'esecuzione di un assemblatore, Intel probabilmente ha scritto un cross-assemblatore che funzionava su uno dei suoi grandi computer e ha tradotto il codice assembly per il 4004 in un'immagine binaria che potrebbe essere programmata nella ROM.


4

Un computer a un livello molto basso può essere rappresentato da un percorso dati e un controllo . Cercare su Google insieme può darti molte letture in quanto è fondamentale nell'architettura / design digitale.

Farò del mio meglio per riassumere:

Come accennato qui, nel cuore abbiamo un ALU - ciò che deve essere conosciuto sull'ALU (e su altre parti della CPU) è che è riconfigurabile per diverse operazioni. Più specificamente, abbiamo la possibilità di riconfigurare il percorso dei dati , ovvero il modo in cui i parametri vengono recuperati, quale operazione fare e dove vengono archiviati in seguito. Immagina di essere in grado di manipolare queste tre cose: questo è il nostro controllo .

Quindi, come possiamo realizzare questo? Come già accennato, possiamo sfruttare la logica digitale di basso livello e creare multiplexer per percorsi diversi. I multiplexer sono controllati usando un set di bit per l'input: da dove vengono presi questi bit? Codificato dalle istruzioni stesse. Il takeaway: istruzioni come mov, add, ecc. Sono solo un insieme di bit che indicano a una CPU come configurare il suo datapath per una particolare operazione. Quello che stai leggendo (mov, add) è la forma leggibile dall'uomo (linguaggio assembly) e il nostro programma definisce una procedura di datapath e operazioni.

Mi scuso se questa è una semplificazione eccessiva di processi più complessi a coloro che sono più informati in questo settore. Cordiali saluti, lo scambio di stack di ingegneria elettrica sarebbe un ottimo posto per porre questa domanda in quanto si occupa di logica di livello molto basso.


3

se capisco la tua domanda non capisco come siano collegati bin / hex o assembly.

Suppongo che la carne della tua domanda sia come posso ottenere dalle porte di base, E, O, NON a istruzioni come spostare, caricare, conservare, aggiungere, ecc.

Ho il mio piccolo set di istruzioni per l'insegnamento che ho fatto da zero che ha alcuni dei dettagli di come funziona un add e sottrarre da cancelli di base e cose del genere http://github.com/dwelch67/lsasim .

Cerca il libro Code (qualcosa qualcosa qualcosa qualcosa) di Petzold. Può iniziare in modo elementare ma ti accompagna lentamente dal nulla a che fare con computer ed elettronica in binari, hex, e nelle porte di base, ecc.

Ti stai chiedendo come ne costruiresti uno da zero oggi, o come hanno fatto in passato? Oggi inizieresti con una definizione del set di istruzioni. ti siedi e scrivi, pensi ai tipi di istruzioni che devi avere i carichi, i depositi, i movimenti e le cose in alluminio, e poi quanti registri, quanto sono grandi i registri, questo in parte influenza la dimensione delle istruzioni, pensi sulla dimensione dell'istruzione ...

Lasciami fermare e chiederti come si scrive un programma? A partire da una schermata vuota su un editor di testo? Hai qualche idea del compito che stai cercando di risolvere le variabili di cui potresti aver bisogno, le funzioni, il linguaggio di programmazione, ecc. E ogni persona è diversa, ma in una certa misura fai un po 'di questo (diciamo di definire e scrivere funzioni), un po 'di quello (creazione di file di intestazione con definizioni ed enumerazioni riutilizzabili, strutture e cose) e un po' dell'altra cosa (solo codice, riempi le funzioni con variabili e codice). E circoli intorno alle diverse attività, alla fine senti di avere un equilibrio tra dimensione del codice, velocità, leggibilità, qualità, funzionalità, ecc. Non è diverso con la progettazione hardware. i progettisti hardware utilizzano anche linguaggi di programmazione (vhdl, verilog) e seguono lo stesso processo,

Proprio come quando si presenta un programma software, si bilanciano i desideri, le prestazioni, le dimensioni, le caratteristiche, ecc. Potresti avere alcune regole di progettazione costrette a te o che volevi o che il tuo capo ti ha fatto fare, ecc. Come con la progettazione del software ben dopo dalla progettazione iniziale all'implementazione potresti scoprire di avere alcuni grossi errori e dover tornare alla progettazione iniziale e cambiare il set di istruzioni, grandi o piccole modifiche. Potrebbe arrivare al punto di avere un compilatore e un processore simulato per scoprire che hai davvero bisogno di un paio di istruzioni specifiche che migliorano notevolmente la qualità del codice compilato, le prestazioni, ecc.

Quindi hai inventato alcune istruzioni da zero, hai usato una certa esperienza con la progettazione hardware per raggruppare istruzioni simili con schemi di bit simili in modo che possano essere decodificati più facilmente, non solo per la programmazione del linguaggio hardware, ma risparmia energia e porte e tutto il resto roba buona. In questi giorni faresti una sorta di simulatore, la mia comprensione è che ARM è stato prima un simulatore software, poi i progetti hardware sono arrivati ​​dopo, non so se sia vero, ma rispecchiamo quella storia. Questo dipende dal team che alcuni team possono essere solo persone hardware e vogliono semplicemente entrare nella programmazione in hdl, alcuni come me potrebbero voler fare un po 'di entrambi. Al giorno d'oggi sono disponibili buoni simulatori di linguaggio hardware, quindi non è necessario creare alcun hardware compilato e simulato e fare gran parte del debug con un programma / pacchetto di simulazione hardware. il team del software può sviluppare assemblatori e compilatori per il set di istruzioni e utilizzare programmi simulati di alimentazione di ram e rom per il processore simulato e metterlo alla prova. abbiamo simulato un avvio completo di Linux su un processore su cui ho lavorato non molto tempo fa, ci sono volute molte ore ma ha funzionato (trovato un bug di cache nella logica in quel modo).

Quindi ora per quello che penso davvero stavi chiedendo. Come si passa da cancelli di base a un processore con un set di istruzioni. Beh, le porte di base E, O, NON sono davvero analogiche, non hanno un concetto di tempo, non puoi cambiare istantaneamente la tensione sugli ingressi e quando cambi quella tensione le uscite iniziano a cambiare. le porte sono fatte di transistor e i transistor sono amplificatori, prendono l'ingresso moltiplicalo per un certo numero e permettono a quella corrente di fluire dall'altra parte. quando li usiamo come porte logiche li stiamo effettivamente sovrasaturando, la tensione di ingresso è così alta o bassa che il transistor può solo pilotare la tensione massima o nessuna tensione (corrente). in pratica il transitor si trasforma in un interruttore. per farla breve, non esiste un concetto di tempo. Per avere un set di istruzioni dobbiamo far accadere le istruzioni per poter seguire il programma in sequenza, dobbiamo avere un concetto di adesso siamo su questa istruzione e nella prossima finestra lavoreremo su quell'istruzione. Proprio come il gioco di trasformare un amplificatore in un interruttore, giochi simili usando le porte logiche di base con un orologio. gli orologi provengono da cristalli magici in una lattina (non vale la pena entrare qui) che creano tensioni che si accendono e si spengono a una velocità fissa. usa quella tensione nelle equazioni logiche e puoi iniziare a mettere in sequenza le cose. gli orologi provengono da cristalli magici in una lattina (non vale la pena entrare qui) che creano tensioni che si accendono e si spengono a una velocità fissa. usa quella tensione nelle equazioni logiche e puoi iniziare a mettere in sequenza le cose. gli orologi provengono da cristalli magici in una lattina (non vale la pena entrare qui) che creano tensioni che si accendono e si spengono a una velocità fissa. usa quella tensione nelle equazioni logiche e puoi iniziare a mettere in sequenza le cose.

pensa molto molto brevemente a questa tabella di verità:

0 0 0
0 1 1
1 0 1
1 1 0

in binario:

0 + 0 = 1
0 + 1 = 1
1 + 0 = 1
1 + 1 = 10 (2 decimal)

concentrandosi solo su lsbit, un sommatore a un bit, la tabella di verità sopra descrive un sommatore a un bit. Descrive anche un gate XOR. Un input è vero o l'altro ma non entrambi.

Per ottenere più di un bit devi guardare i bit di carry in e di carry ed hai bisogno di un sommatore a tre bit di due operandi e di un carry in con due uscite, di carry e del bit di risultato. Una volta che hai quel sommatore a tre input e due output, puoi collegarlo a cascata quanto vuoi. Ma questo è ancora analogico, le porte cambiano all'istante.

Come trasformi questo sommatore analogico in un'istruzione ADD, hai qualche logica che osserva l'istruzione che si trova come input per queste porte che hai organizzato. alcuni dei bit nell'istruzione dicono, questa è un'istruzione add, alcuni dei bit dicono che un operando è tale e tale registro, forse il registro 7, altri bit possono dire che l'altro operando è il registro 4. e a seconda dell'architettura potrebbe avere un altro registro definito nell'istruzione che dice di inserire il risultato nel registro 2. Ora più logica lo vede poiché ho bisogno che i contenuti del registro 7 siano indirizzati a un ingresso di alu adder e gli ingressi del registro 4 instradati al sommatore e tu installi l'output del sommatore da registrare 2. Poiché l'orologio fa parte di questa logica, vi è un periodo di tempo dall'inizio del periodo di clock all'inizio del periodo di clock successivo in cui tutti i segnali analogici si stabilizzano e risolvono l'equazione logica che sono collegati. Non diversamente da quando si gira un interruttore della luce, si cambia lo stato delle luci da spento a acceso. ci vuole un po 'di tempo prima che quella luce si riscaldi e sostanzialmente si stabilizzi. Non molto diverso qui.

C'è una logica che dice cose come se questo periodo di clock è la fase di esecuzione di un'istruzione AND, quindi il prossimo periodo di clock salverò il risultato nel registro di output. allo stesso tempo vado a prendere la prossima istruzione ecc. Quindi per i moderni processori in cui l'esecuzione di alu è spesso solo un periodo di clock perché la logica analogica può risolvere le equazioni logiche così velocemente. I processori più vecchi che dovevi contare per un certo numero lasciano l'addder cablato, attendi il numero x di cicli di clock per la risoluzione della logica dell'adder, quindi campiona il risultato dall'output, alimenta alu diversi input, attendi x il numero di cicli di clock per che per risolvere, ripetere per sempre o fino allo spegnimento.

Cosa intendo per equazioni logiche? solo che, se vuoi, puoi pensarci in termini di porte AND, OR, NOT. Per ogni bit di ingresso al circuito del sommatore alu esiste un'equazione, probabilmente un'equazione molto lunga che include l'orologio, che include i flip flop (bit di memoria singoli / singoli) che contengono l'istruzione corrente (più le equazioni che alimentano ognuna di quelle bit di memoria) e avanti e indietro. Prendi una singola funzione software che hai scritto, nella lingua che hai scritto, supponendo che questa sia una funzione che accetta gli input, esegue un'attività e quindi termina e restituisce un risultato. Pensa a tutte le possibili combinazioni di input e quali sono i diversi percorsi di esecuzione attraverso quella funzione. Potresti averlo scritto in un linguaggio di alto livello ma probabilmente potresti anche riscriverlo in quel linguaggio per renderlo più primitivo e più primitivo usando molte strutture nidificate if-then-else. e forse scendere più in basso nel linguaggio degli assemblaggi. Non diversamente dalle equazioni di cui sto parlando, il programmatore hardware non programma in queste equazioni a lungo fiato più di quanto probabilmente non programmiate in alberi if-then-else lunghi nel linguaggio assembly quando il linguaggio di programmazione scelto salva così tanto. Proprio come il compilatore che usi trasforma il tuo piccolo codice sorgente in un assemblaggio lungo con molti if-then-elses, c'è un compilatore che prende il codice del linguaggio di programmazione hardware e lo trasforma in equazioni logiche.

Ora torniamo alla prima CPU (che oggi considereremmo un microcontrollore ma poi era una CPU). Hai fatto tutto quanto sopra su carta e non hai usato linguaggi di programmazione hardware in realtà hai scritto le equazioni logiche, ma hai ancora più attentamente scelto i modelli di bit per le istruzioni per rendere semplice il numero di porte e fili per collegare quelle porte come pratico. Sulla carta, a mano dovevi creare entrambi la lunga lista di porte logiche cablate e poi dovevi disegnare i componenti reali su una versione ingrandita della maschera al silicio. anche oggi i chip vengono realizzati utilizzando ciò che è simile a un processo fotografico o simile alla serigrafia in termini di laici, in modo da prendere queste stampe blu se lo si desidera e ridurle e applicarle agli strati di silicio.

qui di nuovo nel giorno in cui tutti avevano una migliore gestione dell'assemblaggio e non solo potevi finire per fare un po 'di programmazione dell'assemblaggio, forse non avresti avuto un editor di testo né un assemblatore, potresti aver dovuto scrivere i tuoi primi programmi a mano su carta, quindi usando un manuale di riferimento, convertito a mano in codice macchina, uno e zeri. Su alcuni di quei computer potresti aver dovuto caricare il ram ruotando gli interruttori, capovolgendo i bit degli indirizzi, capovolgendo i bit dei dati fino a quando non corrispondono ai numeri sulla carta, capovolgi l'orologio verso l'alto e verso il basso e hai caricato una posizione di memoria con un byte di un'istruzione del tuo programma, ripeti alcune centinaia di volte di più e spero che tu non faccia errori.

Allo stesso modo in cui il primo lascia dire che il compilatore C è stato probabilmente scritto in qualche altra lingua, allora è diventato self-hosting, riscritto in C e compilato dal primo compilatore C, quindi di nuovo da solo. Quindi i compilatori C sono stati usati per inventare altri linguaggi di programmazione che sono poi diventati self-hosting. Abbiamo inventato i sistemi operativi e gli editor di testo che si sono costruiti su se stessi, ed è tutta magia nera rimasta per alcune persone dietro la tenda nell'angolo da fare ...

Sì, molto lungo, è una grande domanda che richiede anni di studio ed esperienza per essere veramente colti. guarda il mio lsasim, non pretendo di essere un esperto in nulla, ma è un set di istruzioni, c'è sia un simulatore che esegue le istruzioni scritte in C, sia un'altra implementazione del processore implementata in un linguaggio di programmazione hardware che può essere simulato utilizzando strumenti diversi. Inoltre un assemblatore grezzo e alcuni altri strumenti e simili. Forse, esaminando parte di questo, in particolare il codice del linguaggio di programmazione hardware, si potrebbe colmare il divario su ciò che presumo tu stia chiedendo. Se non ho colmato questa lacuna o ho fatto una tangente lunga, per favore fatemi sapere che rimuoverò felicemente questa risposta (supponendo che io non sia in grado di non uscire molto allo scambio di programmatori).


Questo in realtà non risponde alla domanda dell'autore, almeno non aggiunge nulla alla discussione, che la risposta accettata non ha coperto. La tua matematica binaria non è corretta al 100% 1 + 1 è 0 con un overflow di 1. A seconda della dimensione del registro sarebbe 2 o 0.
Ramhound

@dwelch DAMN! Sono il tuo fan sfegatato se non di meno. +1
AceofSpades

2

Le CPU funzionano su 0 e 1. Tutte le istruzioni avevano una sequenza di bit che le definivano. Questo era il codice macchina. È così difficile per gli umani leggere e scrivere. Come primo passo abbiamo raggruppato gli 0 e gli 1 in sequenze di 4 bit e abbiamo usato da 0 a F per rappresentarli. Ciò ha ridotto i numeri che dovevamo memorizzare, ma non era ancora facile ricordare il codice esadecimale per le istruzioni.

Quindi abbiamo iniziato a usare assembly che aveva "parole" come MOV e ADD. L'assemblatore sostituirà le istruzioni con il set corretto di 0 'e 1 convertendo l'assembly "elenco" in codice macchina.

Alla fine abbiamo sviluppato linguaggi di livello "superiore" in cui "istruzioni" potrebbero rappresentare intere sequenze di codice macchina.


Cordiali saluti, l'ottale è stato usato come una scorciatoia binaria prima dell'esadecimale.
ocodo,

Slomojo ha ragione, Octal, la base 8 ha usato 3 bit, è stata usata insieme all'esagono, la base 16 ha usato 4 bit. Octal aveva il vantaggio di sapere tutti quali numeri rappresentavano da 0 a 7. Le persone che non usavano Hex erano spesso confuse dalle "cifre" dalla A alla F.
Jim C

0

Di recente mi sono imbattuto in questo Q / A e circa un anno fa circa quando ho iniziato a percorrere questo percorso; Avrei trovato questa un'ottima risorsa e una pagina di riferimento per quanto riguarda le mie domande correlate.


Parte 1: -Preface-

Un po 'di me:

Dalla metà alla fine degli anni '80, quando ero ancora alla scuola elementare, smontavo stereo stereo, videoregistratore e altri dispositivi elettronici che andavano dagli anni '50 agli anni '80 e guardavano i circuiti stampati e volevo sempre sapere come facevano lavoro ... Come hanno effettivamente acquisito il segnale di trasmissione, prodotto audio, video, fatto questo e quello ecc ... Ho potuto riconoscere le singole parti qua e là come un resister, un condensatore, un diodo e un transistor, ma non lo hanno fatto sapere cosa hanno fatto o come hanno funzionato in così giovane età.

Nel corso degli anni sono sempre stato eccezionale in matematica, fisica e chimica. Ho compreso la matematica in larga misura e ho anche potuto leggere alcuni circuiti semplici o di base della mia scuola media e dei giorni del liceo che sono arrivati ​​dopo, ma non sono mai riuscito a conoscere le porte logiche e il modo in cui sono state costruite ... imparo Algebra booleana al liceo dalla mia lezione di Logica, Probabilità e Statistica. Tutte le mie lezioni di matematica e scienze erano lezioni d'onore. Non ho preso Calculus fino al mio secondo semestre in un college della comunità. Ho provato al College Algebra e ho preso la Trigonometria come corso di aggiornamento. Il mio più alto livello di matematica dalla classe è Calcolo II di una singola variabile.

Gioco ai videogiochi da quando avevo circa 3 o 4 anni. Da bambino avevo Atari, NES, Sega Genesis e PS1. Quando sono cresciuto e ho iniziato la mia adolescenza e all'inizio degli anni 20 avevo acquisito la PS2 e la SNES con titoli scelti preferiti. Anche questo non tiene conto dei giochi per PC che risalgono a Doom!

Sono sempre stato un appassionato giocatore di console e PC e questo non include i giochi di flipper e arcade.

Mi è stato dato il mio primo PC quando avevo circa 12 anni per Natale nei primi anni '90. I giorni di DOS 6.0 e Win 3.11 o OS / 2. Da allora ho sempre avuto familiarità con la famiglia di sistemi operativi "Windows" e tutti i sistemi che ho avuto erano Intel Architecture. Ho avuto un'esperienza limitata con Apple o Mac da scuola o college, ma non ho mai avuto il privilegio di lavorare su sistemi Linux. Ho Cygwin e ho provato a imparare bash, ma sono così abituato a Dos o alla sintassi del prompt dei comandi.

All'inizio degli anni '90 avrei ottenuto una copia o due di PC-World e avrei inserito i frammenti di codice in QBasic che non conoscevo molto bene e che avrei provato a far funzionare quei programmi. L'unico successo è stato un programma per trasformare i tasti premuti sulla riga di tasti home in diversi suoni di suoneria. Non intendo le suonerie su un telefono cellulare, intendo una frequenza continua finché si tiene premuto il tasto.

È sempre stata una mia passione non solo voler sapere come funzionavano i dispositivi elettronici all'interno della circolazione a livello digitale e logico, imparare a programmare un computer, ma ho sempre avuto il desiderio di voler realizzare il mio video Giochi. Già nei primi anni '90 volevo realizzare i giochi Frogger e Tetris ...


Questa è diventata la mia motivazione principale e il desiderio di affrontare uno dei tipi più difficili di programmazione o sviluppo software nel campo dell'Informatica e questo è il 3D Game Engine Design. Ci sono altri campi in Informatica che sono altrettanto difficili, tuttavia qualsiasi motore di gioco sofisticato in genere o di solito li include quasi tutti poiché i singoli componenti o motori secondari richiedono le loro tecniche e proprietà.

Ho avuto un po 'di esperienza nella programmazione dai miei giorni di scuola superiore, ma questo era limitato all'orribile Visual Basic. Ho iniziato a studiare e imparare C / C ++ tra il 2002 e il 2003 non fino a pochi anni dopo essermi diplomato al liceo nel 1999. Ancora oggi non ho alcuna esperienza universitaria in Informatica o Ingegneria Informatica, ma attraverso dedizione e determinazione, ho imparato quasi ogni concetto che esiste quando si tratta di computer, hardware, programmazione, algoritmi, ecc. e continuo ancora ad imparare il più possibile ...

Durante i primi giorni di apprendimento del C / C ++, avevo accesso a Internet ma Internet era nelle sue fasi iniziali, siti web come Amazon, Youtube, Facebook ecc. Non esistevano ancora, erano ancora i giorni di 56k comporre modem che ottimizzano la linea telefonica se non si dispone di una seconda linea dedicata. Occorrerebbero pochi minuti solo per il rendering di un'immagine sullo schermo, per non parlare della riproduzione video continua.

Quindi, quando si trattava di ricerca e apprendimento su come programmare in C ++, le risorse erano limitate e la maggior parte erano in formato testo. Quando hanno tentato di affrontare i progetti fin dai primi giorni di esercitazione su Internet, molti di questi progetti non erano completamente completi, gli scrittori erano professionisti o studenti universitari e hanno fatto molte ipotesi che il lettore avesse già familiarità con molti dei concetti necessari come la compilazione , collegamento e debug e integrazione della libreria.

Per qualcuno che non sa nulla di quegli argomenti, sono in perdita perché non sanno cosa è andato storto, né come risolverlo, e come farlo funzionare correttamente. Mi ci sono volute molte ore di tentativi ed errori in quei giorni con risorse molto limitate. Chiedere aiuto come possiamo ora con questo sito Web o cercare spiegazioni dettagliate che puoi trovare su cppreference non era disponibile! Se personalmente non conoscevi nessuno, non ce n'erano così tanti a cui rivolgersi per ricevere assistenza!

Col passare del tempo ho migliorato alcune delle mie conoscenze qua e là, e alla fine Internet è migliorato con DSL, e ora Internet ad alta velocità, i siti Web sono diventati più interattivi, i video hanno iniziato a comparire, la qualità dei video è migliorata con il tempo, siti come quando Youtube ha iniziato a mostrarsi e le cose sono diventate un po 'più facili dal punto di vista della ricerca. Sempre più tutorial diventarono prontamente disponibili, alcuni erano buoni e utili dove altri insegnavano cattive pratiche ...

Avevo anche dedicato molto tempo alla ricerca e all'acquisizione degli strumenti necessari per lo sviluppo. Ho dovuto imparare la sintassi del linguaggio, il compilatore e il processo di compilazione, collegamento, costruzione e debug. Quindi ho dovuto imparare a conoscere le diverse librerie e API disponibili che sono disponibili e come configurare i miei progetti o soluzioni per collegare tutte queste dipendenze.

Nel corso degli anni ho visto il linguaggio C ++ crescere, evolversi e adattarsi nel tempo. All'inizio è rimasto quasi lo stesso per molti anni, ma negli ultimi 10 anni è cambiato radicalmente in questo breve arco sin dal suo inizio.

Cito tutto questo perché il C ++ è uno dei linguaggi più difficili da padroneggiare completamente per la sua versatilità, potenza, ricco set di funzionalità e la capacità di permettervi di spararvi ai piedi! E anche con tutti i suoi avvertimenti, è uno dei linguaggi più potenti e preferiti che viene utilizzato nel settore leader come standard per questo tipo di sviluppo perché quando fatto correttamente è veloce, conciso, affidabile e utilizza il impronta del piede più piccola.

Da allora sono autodidatta in C / C ++ da molti anni con l'intento e il focus sull'apprendimento della programmazione grafica 3D e del Game Engine Design. Ho impiegato da 100 a 1.000 ore di ricerca, ricerca e molto altro nella lettura, nell'apprendimento e nell'applicazione di tali conoscenze nella progettazione di utili prodotti e applicazioni utili. Ho sempre avuto la volontà e il desiderio di voler saperne di più per migliorare le mie abilità e abilità.


Questo è stato il primo stadio, quindi ho iniziato a leggere e lavorare inizialmente con DirectX 9.c, che ho fatto in C / C ++ e persino in C #. Quindi sono passato a DirectX 10 e Legacy OpenGL 1.0. Dal loro sono usciti DirectX 11 e OpenGL 3.x - 4.x e ora ho persino provato la mia mano su Vulkan.

Ho creato motori di gioco di successo lavorando attraverso vari tutorial online sia in formato testo che video. Ho già affermato di avere una solida preparazione in matematica, ma era limitata al Calcolo I e II. Ho dovuto insegnare a me stesso il calcolo vettoriale di cui avevo una certa conoscenza dalla mia classe di fisica basata sul calcolo al college, ma per quanto riguarda l'algebra lineare con trasformazioni affine e geometria analitica ho dovuto impararli da solo quando certe equazioni, funzioni, metodi, algoritmi e erano necessari concetti. Quindi ho dovuto imparare a tradurli in un codice efficiente, leggibile, affidabile e riutilizzabile che fosse generico e privo di bug, impiegando centinaia o migliaia di ore di debug.

È stato un viaggio meraviglioso imparare gli argomenti e gli algoritmi che includono la gestione della memoria, il conteggio dei riferimenti, l'istanziazione, la ricorsione e molto altro che vengono utilizzati all'interno di molti, se non tutti, i componenti di un motore di gioco in cui sono vasti. Potrei elencarli tutti qui, ma sarebbero sufficienti per riempire 3 o 4 spazi di risposta che vale la pena scrivere. Tuttavia, includerò l'elenco degli argomenti generali, non solo i loro argomenti secondari.

Ecco gli argomenti o l'elenco degli argomenti in ciò che consiste in un motore di gioco completamente funzionale che include tutte le varie tecniche di rendering, impostazione di pipeline di rendering e shader, tecniche di ombreggiatura e illuminazione tramite shader, pre e post elaborazione, frame buffer, back buffer , caricamento delle immagini, caricamento e analisi dell'audio e del modello, creazione di forme primitive con proprietà del materiale di colore, trama e coordinate normali con mappatura manuale delle trame, trasformazioni di oggetti, tipi di videocamera, gerarchie di grafici di scena, classi manager per trame, audio, caratteri e shader e gestione della memoria, sistema di registrazione con gestione delle eccezioni, tecniche di programmazione multi-thread e parallele, collegamento in rete, motore fisico, rilevamento delle collisioni, generatore di particelle, animazione, AI del gioco, generazione del terreno, sky box e sky-dome, rendering dell'acqua,fogliame e altro ancora ..., GUI con font strutturato per il rendering del testo, overlay HUD, inventari, generazione di mappe e macro, sistema statale e macchine a stati, e infine scrivere un parser per creare il proprio linguaggio di scripting per automatizzare gran parte di questi oggetti la possibilità di modificare i valori dei dati all'interno del motore senza dover ricompilare semplicemente caricando i file di dati per popolare gli oggetti dati e le strutture all'interno dei rispettivi contenitori all'avvio dell'applicazione.e infine scrivere un parser per creare il proprio linguaggio di scripting per automatizzare gran parte di questi oggetti per avere la possibilità di modificare i valori dei dati all'interno del motore senza dover ricompilare semplicemente caricando i file di dati per popolare gli oggetti e le strutture dei dati nei rispettivi contenitori all'avvio dell'applicazione.e infine scrivere un parser per creare il proprio linguaggio di scripting per automatizzare gran parte di questi oggetti per avere la possibilità di modificare i valori dei dati all'interno del motore senza dover ricompilare semplicemente caricando i file di dati per popolare gli oggetti e le strutture dei dati nei rispettivi contenitori all'avvio dell'applicazione.


Nel corso degli anni sono stato incuriosito dalla voglia di imparare il linguaggio degli assemblaggi, dai loro volevo conoscere compilatori, assemblatori e semplici sistemi operativi, intendo il loro funzionamento interno, come sono costruiti e progettati.

Il tempo è passato e poi ho fatto un passo un po 'di lato e ho iniziato a studiare l'emulazione hardware. Mi sono concentrato in particolare sul NES ma volevo imparare l'emulazione hardware delle CPU in generale. Questo mi ha portato a conoscere il set di istruzioni in cui già conoscevo il concetto e quello che era poiché conoscevo già in qualche modo la famiglia x86 di Intel, ma ora ho dovuto imparare il set di istruzioni 6502.

Eppure, immergendomi in questo, ho finito per fare ulteriori ricerche e ho iniziato a conoscere l'architettura del set di istruzioni da una prospettiva ingegneristica. Questo mi ha portato a imparare come è costruita la CPU dalle porte logiche e come sono costruite le porte logiche dai transistor insieme ad altri vari componenti elettrici. Così ho finito per imparare questo da due prospettive dall'alto verso il basso e dal basso verso l'alto. Entrambi i metodi sono stati molto efficaci e penso che imparare da entrambi aiuti a costruire quel ponte o gap in cui il software batte l'hardware.

Da questo, ho dovuto rinfrescarmi sulla mia algebra booleana e ho finito per conoscere K-Maps, le tabelle delle implicazioni, le macchine statali sia Mealy e Moore e varie altre cose che collegano la logica binaria e l'aritmetica alle porte logiche fisiche e ai circuiti integrati. E questo mi porta al passato risentito in cui ho iniziato a lavorare con Logisim e ho iniziato a studiare HDL, VHDL, Verilog ecc ...

Ho imparato tutto questo nel mio tempo libero, quando ho potuto negli ultimi 15-18 anni.


Ecco alcuni dei siti e dei collegamenti che mi hanno guidato negli anni. Molti di questi sono recenti poiché molti dei siti da cui ho imparato originariamente non esistono più, ho perso i loro collegamenti e non ricordo, oppure i motori di ricerca li hanno spinti in fondo alle loro liste di ricerca ...

  • Lingue - C ++

  • Tutorial sulla grafica 3D e siti Web di risorse

  • Le serie e i canali di Youtube trattano gli argomenti sopra, nonché hardware, computer ed ingegneria elettrica. Ce ne sono troppi da elencare, quindi ne elencherò alcuni qui che trovo più utili e pieni di risorse. Non fornirò i link ma puoi cercare su YouTube questi canali.

    • 3Blue1Brown - Matematica avanzata
    • Bisqwit - Programmazione C / C ++ avanzata (progetti applicativi) - Emulatore hardware NES
    • Jason Turner - Tecniche avanzate di programmazione C ++ moderna
    • javidx9 - Programmazione C / C ++ avanzata (progetti applicativi) - Emulatore hardware NES / Some Assembly
    • MIT OpenCourse - Corsi universitari in matematica e informatica
    • Corsi online Bilkent - Corsi universitari in informatica e ingegneria informatica (CPU Design MIPS)
    • The Cherno - Temi e applicazioni di programmazione avanzata C / C ++ - Sviluppo di motori di gioco
    • Ben Eater - Hardware Engineering - Applicazione pratica tramite breadboard
    • Neso Academy - Ingegneria Hardware - Teoria e concetti
    • Socratica - Programmazione Python
    • In poche parole - Ingegneria hardware - Teoria e concetti
    • Bitwise : Advanced C / C ++ Progettazione di un assemblatore tramite emulazione hardware
    • Bo Qian - C ++ Argomenti su strutture dati e algoritmi.
    • LineByLine - Programmazione Vulkan
    • Joshua Shucker - Programmazione Vulkan
    • www.MarekKnows.com - Sviluppo C ++, 3D Math e Game Engine

E questi non tengono conto di alcuni dei vari libri che ho su questi argomenti.

-Nota- Per favore, non votare su questo in quanto questo è solo un messaggio per il lettore della mia esperienza personale ed è privo di qualsiasi tentativo di rispondere o fare riferimento alla domanda originale. Nei prossimi due giorni quando avrò il tempo; Aggiungerò una risposta di follow-up per esprimere la mia opinione sulla domanda del PO fornendo al contempo collegamenti utili come riferimento e insieme di risorse e aggiornerò anche questa risposta per includere alcuni collegamenti qui e modificare questa nota. È tardi e al momento non ho il tempo di correggere e modificare ciò che ho già scritto. Lo farò quando posso ".


Ho appena aggiornato questa risposta o post. Stavo per aggiungere la seconda parte che risponderà effettivamente alla domanda, tuttavia non ho abbastanza punti reputazione per farlo. Mi ci vorrà del tempo per costruire i punti reputazione necessari prima di poter aggiungere la mia seconda risposta. Questo post non è la risposta effettiva, ma lo userò come riferimento e cercherò una tabella nel ragionamento della mia vera risposta. È necessario disporre di alcune delle risorse elencate sopra per contribuire a colmare il divario tra software e hardware.
Francis Cugler,

-2

Al suo centro, una CPU è di solito solo una macchina a stati. Quindi dovrai capire come si combinano porte logiche, infradito o registri per creare macchine a stati.

Una macchina a stati prende input e lo stato corrente, li esegue attraverso una logica booleana (e potenzialmente aritmetica), quindi fornisce output e uno stato successivo. Uno degli ingressi può essere il registro delle istruzioni. Una delle uscite può essere un'abilitazione e una selezione per la sorgente per ricaricare il registro delle istruzioni, magari anche per incrementare o caricare un altro registro che funge da contatore del programma. Con ciò, oltre ad un po 'di memoria indirizzabile, è possibile scorrere le istruzioni in sequenza.

Una volta che hai un modo per sequenziare le istruzioni, puoi usare la logica per decodificare questi bit di istruzioni, oltre allo stato corrente, in un altro gruppo di bit di controllo. Alcuni di questi bit di controllo possono fungere da input per controllare un gruppo di logica in grado di eseguire la logica aritmetica e dell'intera parola, chiamandola ALU. Altri bit possono caricare oggetti o selezionare input per ALU. Altri bit possono dire dove archiviare i risultati dell'ALU. Oppure carica i registri di indirizzamento. Oppure scrivi in ​​memoria o altre uscite. Eccetera.

Parte della progettazione di un set di istruzioni è solo capire quali combinazioni di bit, quando decodificati, controllano tutti i registri e il sequenziamento della macchina a stati. Ciò era stato fatto e (ri) ottimizzato migliaia di modi diversi.

Esistono almeno 3 livelli di libri di testo universitari su questo argomento non banale.


2
Questo non spiega come l'operazione MOV sia convertita in valore binario. Questo non menziona l'istruzione MOV che è un valore, è una parola chiave che usiamo, quindi non dobbiamo memorizzare un valore binario da 16 a 32 bit.
Ramhound,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.