Fondamentalmente ogni computer moderno è una macchina che spinge i bit. Solitamente sposta i bit in gruppi di dati, chiamati byte, parole, parole o parole chiave.
Un byte è composto da 8 bit, una parola 2 byte (o 16 bit), una parola 2 parole (o 32 bit) e una parola q 2 parole (o 64 bit). Questi non sono l'unico modo per disporre i bit. Si verifica anche la manipolazione a 128 e 256 bit, spesso nelle istruzioni SIMD.
Le istruzioni di assemblaggio operano su registri e gli indirizzi di memoria normalmente operano in una delle forme sopra indicate.
Gli ALU (unità logiche aritmetiche) operano su tali fasci di bit come se rappresentassero numeri interi (di solito il formato del complemento a due) e FPU come se fossero valori in virgola mobile (di solito in stile IEEE 754 float
e double
). Altre parti si comporteranno come se fossero dati raggruppati di un certo formato, caratteri, voci della tabella, istruzioni della CPU o indirizzi.
Su un tipico computer a 64 bit, i bundle di 8 byte (64 bit) sono indirizzi. Visualizziamo questi indirizzi in modo convenzionale come in un formato esadecimale (come 0xabcd1234cdef5678
), ma questo è solo un modo semplice per gli umani di leggere i modelli di bit. Ogni byte (8 bit) è scritto come due caratteri esadecimali (equivalentemente ogni carattere esadecimale - da 0 a F - rappresenta 4 bit).
Ciò che sta realmente accadendo (per un certo livello di realtà) è che ci sono bit, di solito memorizzati in un registro o memorizzati in posizioni adiacenti in un banco di memoria, e stiamo solo cercando di descriverli a un altro essere umano.
Seguire un puntatore consiste nel chiedere al controller di memoria di fornirci alcuni dati in quella posizione. Generalmente chiedete al controller di memoria un certo numero di byte in una determinata posizione (beh, implicitamente una serie di posizioni, di solito contigue), e viene fornito attraverso vari meccanismi in cui non entrerò.
Il codice di solito specifica una destinazione per il recupero dei dati - un registro, un altro indirizzo di memoria, ecc. - Di solito è una cattiva idea caricare i dati in virgola mobile in un registro in attesa di un numero intero o viceversa.
Il tipo di dati in C / C ++ è qualcosa di cui il compilatore tiene traccia e cambia il codice generato. Di solito non c'è nulla di intrinseco nei dati che lo rende effettivamente di alcun tipo. Solo una raccolta di bit (disposti in byte) che vengono manipolati in modo intero (o in modo float o in modo indiretto) dal codice.
Ci sono delle eccezioni. Ci sono architetture in cui certe cose sono un diverso tipo di bit. L'esempio più comune sono le pagine di esecuzione protette - mentre le istruzioni che indicano alla CPU cosa fare sono bit, in fase di esecuzione le pagine (di memoria) contenenti codice da eseguire sono contrassegnate in modo speciale, non possono essere modificate e non è possibile eseguire pagine che non sono contrassegnate come pagine di esecuzione.
Esistono anche dati di sola lettura (a volte memorizzati nella ROM su cui non è possibile scrivere fisicamente!), Problemi di allineamento (alcuni processori non possono caricare messaggi double
di memoria a meno che non siano allineati in modi particolari o istruzioni SIMD che richiedono un certo allineamento) e miriadi di altre stranezze di architettura.
Anche il livello di dettaglio sopra riportato è una bugia. I computer non "spingono" veramente i bit, ma spingono davvero tensioni e correnti. Queste tensioni e correnti a volte non fanno ciò che dovrebbero "fare" al livello di astrazione dei bit. I chip sono progettati per rilevare la maggior parte di tali errori e correggerli senza che l'astrazione di livello superiore debba esserne consapevole.
Anche questa è una bugia.
Ogni livello di astrazione nasconde quello sottostante e ti consente di pensare a risolvere i problemi senza dover tenere a mente i diagrammi di Feynman per poterli stampare "Hello World"
.
Quindi, a un livello sufficiente di onestà, i computer spingono i bit e questi bit ricevono significato dal modo in cui vengono utilizzati.