In che modo un computer determina il tipo di dati di un byte?


31

Ad esempio, se il computer ha 10111100archiviato un determinato byte di RAM, come fa il computer a interpretarlo come un numero intero, un carattere ASCII o qualcos'altro? I dati di tipo sono memorizzati in un byte adiacente? (Non penso che questo sarebbe il caso in quanto ciò comporterebbe l'utilizzo del doppio della quantità di spazio per un byte.)

Sospetto che forse un computer non conosca nemmeno il tipo di dati, che solo il programma che lo utilizza lo sa. La mia ipotesi è che, poiché la RAM è R AM e quindi non viene letta in sequenza, quel particolare programma dice alla CPU di recuperare le informazioni da un indirizzo specifico e il programma definisce come trattarle. Ciò sembrerebbe adattarsi alle cose di programmazione come la necessità di digitare in modo tipografico.

Sono sulla buona strada?


4
Come nota a margine: se stai parlando di tipi, devi farlo in un contesto linguistico. È lasciato al compilatore per gestire quel genere di cose (simboli, tipi di controllo, operazioni, casting, indirizzo ram, ecc.). CPU e RAM conoscono solo byte
jean

4
Il tipo di dati di un byte è un byte. Oltre a ciò, il computer non sa nulla. Un programma potrebbe interpretare un byte o un gruppo di byte come un particolare tipo di dati e tentare di eseguire operazioni su questi, ma non ci sono restrizioni. Lo stesso gruppo di byte può essere interpretato come più di un tipo di dati (ad es. Lanciare puntatori su tipi di valore, unioni di tipo C, ecc.). Che la RAM non venga letta in sequenza non è rilevante. - È più perché la RAM è di uso generale. - Anche i registri, ad esempio, non vengono letti in sequenza, ma vengono digitati.
BrainSlugs83

5
Spina spudorata per me stesso, ma questa domanda è stata sostanzialmente posta ai programmatori SE circa un mese fa. Ecco la mia risposta . È un po 'lungo a questo punto, ma lo attacca da diverse angolazioni.
Shaz,

2
Una conseguenza utile del fatto che l'hardware è indipendente dal tipo di dati è che un singolo byte (o parola, ecc.) Può essere interpretato in più modi da un programma. In particolare, l'interpretazione temporanea di un numero in virgola mobile come numero intero viene utilizzata per calcolare la radice quadrata inversa veloce .
Aoeuid,

@ BrainSlugs83, potresti considerare di convertirlo in una risposta?
DW

Risposte:


38

Il tuo sospetto è corretto. Alla CPU non interessa la semantica dei tuoi dati. A volte, però, fa la differenza. Ad esempio, alcune operazioni aritmetiche producono risultati diversi quando gli argomenti sono semanticamente firmati o non firmati. In tal caso, è necessario comunicare alla CPU quale interpretazione si intendesse.

Spetta al programmatore dare un senso ai suoi dati. La CPU obbedisce solo agli ordini, beatamente inconsapevoli del loro significato o dei loro obiettivi.


1
Per quanto riguarda "quando gli argomenti sono semanticamente firmati o non firmati", come potrebbe sapere la CPU? Le operazioni della CPU vedono solo i byte dei parametri e non hanno quel tipo di consapevolezza del contesto del tipo di dati. Si implica il tipo di dati scegliendo l'operazione CPU appropriata (o il compilatore lo fa).
Shiv

4
@Shiv In questi casi, alla CPU vengono effettivamente impartite istruzioni diverse per elaborare i numeri con segno rispetto a quelli senza segno. Come nei sospetti del PO, il programma è tenuto a fornire tali dettagli, poiché la CPU non è a conoscenza.
Cort Ammon - Ripristina Monica il

2
Lavoro con i computer da quando mi ricordo di me stesso e anche se so che la CPU non si preoccupa dei costrutti di alto livello che usiamo sulla programmazione di alto livello, ma questa separazione di concetti mi fa ancora impazzire di tanto in tanto
Loupax,

1
@Loupax Bene, lavorare con un assembly veramente di basso livello aiuta parecchio - anche se mov al, 42è un po 'di alto livello - è ovvio che c'è solo una possibile istruzione che questa potrebbe chiamare, ma è comunque un po' astratta. Tuttavia, l'utilizzo mov.8 al, 42esplicito lo rende dolorosamente ovvio :)
Luaan,

1
@Shiv: vorrei notare che ci sono macchine in cui vengono digitati i dati in memoria. Queste sono chiamate architetture di memoria con tag (o semplicemente architetture con tag) ma non hanno avuto tanto successo commerciale quanto le architetture normali, in parte perché ora programmiamo principalmente in linguaggi compilati anziché in assembly e il compilatore si occupa della digitazione. Vedi: en.wikipedia.org/wiki/Tagged_architecture
slebetman

14

Come altri hanno già risposto, le comuni CPU di oggi non sanno cosa contiene una determinata posizione di memoria; decide il software.

Tuttavia, ci sono altre possibilità. Lisp Machines, ad esempio, utilizzava un'architettura taggata che memorizzava il tipo di ogni posizione di memoria; in questo modo l'hardware stesso potrebbe svolgere parte del lavoro di linguaggi di alto livello.

E anche ora, immagino che potresti considerare il bit NX in Intel, AMD, ARM e altre architetture seguire lo stesso principio: distinguere a livello hardware se una determinata zona di memoria contiene dati o istruzioni.

Inoltre, solo per completezza, nelle architetture di Harvard (come alcuni microcontrollori) i dati e le istruzioni sono fisicamente separati, quindi la CPU ha qualche idea di ciò che sta leggendo.

In questa domanda di Quora ci sono alcuni commenti su come ha funzionato la memoria taggata, le sue implicazioni sulle prestazioni e la fine, e altro ancora.


L'architettura contrassegnata è una nota interessante. Sarebbe significativamente più veloce?
Bassinator

4

Sì. Il programma ottiene solo un byte dalla memoria e può interpretarlo come vuole.


3

Non ci sono annotazioni di tipo.
La RAM memorizza i dati puri e quindi il programma definisce cosa fare.

Con i registri della CPU è un po 'più difficile, se hai registri di un determinato tipo (come FPU), dici cosa c'è dentro.
Le operazioni sui registri a virgola mobile utilizzano esplicitamente i dati digitati. Tu o il tuo compilatore dite cosa e quando dovrebbero essere messi lì, quindi non avete tale libertà.
Il computer non fa alcuna ipotesi sui dati sottostanti nella RAM e nei registri con un'eccezione: i registri digitati nella CPU sono di tipo noto, ottimizzati per gestirli. Questo serve solo a mostrare che ci sono luoghi in cui i dati devono essere del tipo previsto, ma nulla ti impedisce di lanciare stringhe su float e moltiplicarli.

Nei linguaggi di programmazione si specifica il tipo, o nei linguaggi di livello superiore i dati sono generali e il compilatore / interprete / VM codifica ciò che è dentro con l'overhead.
Ad esempio in C il tipo di puntatore indica cosa fare con i dati, come accedervi.

Naturalmente puoi leggere stringhe (caratteri) e trattarle come valori in virgola mobile, numeri interi e mescolarli.


Anche i bit in un registro FPU non rappresentano sempre valori in virgola mobile. Ai vecchi tempi (forse non più?), Un'ottimizzazione comune consisteva nell'utilizzare registri a virgola mobile (64 bit o più grandi) per copiare i dati più velocemente dei registri di uso generale / interi (32 bit), essendo due volte più grandi, erano generalmente in grado di copiare i dati due volte più velocemente.
Seth,

1
Sono totalmente d'accordo con te, ecco perché ho scritto che qualcuno potrebbe spingere le corde lì. E allo stesso tempo le persone eseguivano operazioni in virgola mobile su numeri interi, perché era più veloce. Questo è il punto!
Evil

@HCBPshenanigans ci sono istruzioni che manipolano i valori in virgola mobile. Se si utilizza FADD, ha senso solo che i gruppi di memoria (4,8, o 10) a byte contenessero numeri in virgola mobile. Questo è vero per diversi tipi di istruzione: moltiplicare due numeri interi ha senso solo se sono numeri interi, saltare ha senso solo se è un indirizzo.
JDługosz,

@seth and evilJS che non si presume sia il caso di istruzioni in pila a virgola mobile legacy 8087, ma è il caso dei registri CIMD più recenti che possono essere utilizzati solo per il caricamento / salvataggio senza interpretazione (anche se devono essere allineati) e un avvertimento che se i registri CIMD non sono mai stati utilizzati, non è necessario salvarli in un cambio di contesto. Se si sposta (solo) 8 byte tramite il registro XMM è una perdita netta poiché è necessario salvare l'intero set.
JDługosz,

3

Alla CPU non importa, esegue il codice assembly, che semplicemente sposta i dati, li sposta, li aggiunge o li moltiplica ...

I tipi di dati sono un concetto di linguaggio di livello superiore: in C o C ++ è necessario specificare i tipi per ogni singolo dato manipolato; il compilatore C / C ++ si occupa di trasformare questi dati in comandi corretti per l'elaborazione della CPU (i compilatori scrivono il codice assembly)

In alcuni linguaggi di livello ancora superiore, i tipi possono essere dedotti: in Python o Javascript, ad esempio, non è necessario specificare i tipi di dati, tuttavia i dati hanno un tipo e non è possibile aggiungere una stringa con un numero intero, ma è possibile aggiungere un float con un numero intero: il 'compilatore' (che nel caso di Javascript è un compilatore JIT (Just in Time). Javascript è spesso chiamato un linguaggio 'interpretato' perché i browser storicamente interpretano il codice Javascript, ma oggigiorno i motori Javascript sono compilatori.

Codice, finisce sempre per essere compilato in codice macchina, ma ovviamente il formato del codice macchina dipende dalla macchina che stai prendendo di mira (il codice x86 64 bit non funzionerà su una macchina x86 32 bit o un processore ARM, ad esempio)

Quindi in realtà ci sono molti livelli coinvolti nell'esecuzione del codice interpretato.

Java e C # sono altri interessanti, dal momento che il codice Java o C # è tecnicamente 'compilato' in un binario Java (bytecode), ma quel codice stesso viene quindi interpretato da Java Runtime, che è specifico dell'hardware sottostante (è necessario installare JRE indirizzato alla macchina giusta per eseguire i binari Java (Jars))


Viene compilato un compilatore, che sia JIT o no; e un interprete interpreta senza compilare (perché se non fosse un compilatore!). Sono cose molto diverse. E per quanto riguarda "Java che è divertente" a causa dell'interpretazione del bytecode, considera che anche il codice macchina x86 verrà effettivamente interpretato (o addirittura compilato?) Dal microprocessore in un microcodice .
Hmijail,

Grazie per il chiarimento ... D'accordo: un compilatore compila e un interprete interpreta. Nel caso di Javascript, tuttavia, la storia è un po 'complicata poiché alcuni browser più vecchi interpretano il codice, mentre i browser più moderni in realtà compilano just-in-time, motivo per cui viene ancora definito un linguaggio "interpretato" anche se tecnicamente non è più.
MrE

Ma AFAIK, JS inizia interpretato e quindi potrebbe essere compilato secondo necessità. E i JIT possono passare da interpretati a compilati a interpretati di nuovo, a seconda di molte cose. Ad esempio, un pezzo di codice potrebbe essere compilato per una variabile con un determinato tipo; ma poi il codice viene eseguito di nuovo con quella variabile che ha un tipo diverso, quindi il codice compilato esistente non può essere usato in modo che l'interprete salti dentro - fino a quando il codice non viene compilato di nuovo per il nuovo tipo ...
hmijail

Mi stai citando qualcosa che non ho detto, per favore rimuovilo perché è totalmente sbagliato. Il microcodice non ha NIENTE a che fare con il sistema operativo; è qualcosa di interno al microprocessore. Anche 32 bit o 64 bit non hanno nulla a che fare con esso.
Hmijail,

3

I tipi di dati non sono una funzionalità hardware. La CPU conosce un paio (bene, molti) di comandi diversi. Quelli sono chiamati set di istruzioni di una CPU.

Uno dei più noti è il set di istruzioni x86 . Se cerchi "moltiplica" in questa pagina, otterrai 50 risultati. MULPDe MULSDper la moltiplicazione dei doppi, FIMULper la moltiplicazione dei numeri interi, ...

Quei comandi funzionano sui registri. I registri sono slot di memoria che possono contenere un numero fisso di bit (spesso 32 o 64, a seconda dell'architettura utilizzata dalla CPU), indipendentemente da ciò che questi bit rappresentano. Quindi l'istruzione CPU interpreta i valori dei registri in modo diverso, ma i valori stessi non hanno tipi.

Un esempio è stato dato al PyCon 2017 da Stuart Williams :

inserisci qui la descrizione dell'immagine


1
Si noti che questo non è strettamente vero: esistono registri per scopi speciali che non possono contenere valori arbitrari (ad esempio registri puntatori che non sono solo indirizzi e non consentono aggiunte arbitrarie o registri a virgola mobile dove è possibile memorizzare valori non normalizzati). Ma la tua risposta è corretta per i registri di uso generale sulla maggior parte delle architetture.
Gilles 'SO- smetti di essere malvagio' il

2

... che un determinato programma dice alla CPU di recuperare le informazioni da un indirizzo specifico e il programma definisce come trattarlo.

Esattamente. Ma la RAM non viene letta "sequenzialmente", e sta per Random Access Memory, che è esattamente l'opposto.

Oltre a conoscere ciò che un byte è , non si sa nemmeno se si tratta di un byte , o di un frammento di un oggetto grande come un numero in virgola mobile.

Vorrei aggiungere altre risposte fornendo alcuni esempi specifici.

Considerare 01000001. Il programma potrebbe copiarlo da un luogo a un altro come parte di un grande pacchetto di dati senza alcun riguardo al suo significato. Ma copiarlo nell'indirizzo utilizzato dal buffer video in modalità testo farà Aapparire la lettera in una posizione sullo schermo. La stessa identica azione quando la scheda è in modalità grafica CGA visualizzerà un pixel rosso e un pixel blu.

In un registro, potrebbe essere il numero 65 come numero intero. Fare l'aritmetica per impostare il bit dei 32 potrebbe significare qualsiasi cosa senza contesto, ma potrebbe in particolare cambiare una lettera in minuscolo.

La CPU 8086 (ancora) ha istruzioni speciali chiamate DAA che vengono utilizzate quando il registro contiene 2 cifre decimali, quindi se hai appena usato quell'istruzione la stai interpretando come due cifre 41.

I programmi si arrestano in modo anomalo perché viene letta una parola di memoria pensando che sia un puntatore quando in caso contrario è stato memorizzato qualcosa.

Utilizzando un debugger, ispezionando la memoria, viene utilizzata una mappa per guidare l'interpretazione per la visualizzazione. Senza queste informazioni sui simboli, un debugger di basso livello ti consente di specificare: mostra questo indirizzo come parole a 16 bit, mostra questo indirizzo come punto mobile lungo, come stringhe ... qualunque cosa. Guardando un dump di pacchetti di rete o un formato di file sconosciuto, scervellarlo è una sfida.

Questa è una delle principali fonti di energia e flessibilità nella moderna architettura informatica: una cella di memoria può significare qualsiasi cosa , dati o istruzione, impliciti solo in ciò che "significa" per il programma da ciò che fa con il valore e in che modo influisce sulle operazioni successive. il significato è più profondo della larghezza intera: questi caratteri sono ... caratteri in ascii o ebcdic? Formare parole in inglese o codici prodotto SQU? L'indirizzo da inviare o l'indirizzo di ritorno da cui proviene? L'interpretazione di livello più basso (bit logici; di tipo intero, con segno o senza segno; float; bcd; puntatore) è contestuale al livello di set di istruzioni, ma vedi che è tutto contesto a un certo livello: il tol'indirizzo è quello che è a causa della posizione è stampato sulla busta. È contestuale alle regole del postino, non della CPU. Il contesto è un grande continuum, con bit su un'estremità.


※ Nota a piè di pagina: l'istruzione DAA è codificata come byte 00100111. Quindi quel byte è l'istruzione aforenamed se letto nel flusso di istruzioni e le cifre 27se interpretate come cifre bcd e 0x27 = 39 come numero intero, che è il numero 9 in ASCII e parte della tabella degli interrupt (metà di INT 13 Indirizzo a 2 byte, utilizzato per le routine di servizio BIOS).


1

L'unico modo in cui il computer sa che una posizione di memoria è un'istruzione è che un registro per scopi speciali chiamato il puntatore dell'istruzione punta a loro in un punto o nell'altro. Se il puntatore dell'istruzione punta a una parola di memoria, viene caricato come un'istruzione. A parte questo, il computer non ha modo di conoscere la differenza tra programmi e altri tipi di dati.

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.