In che modo la stessa sequenza di byte può rappresentare un numero intero, un numero in virgola mobile, una stringa di caratteri o un'istruzione macchina?

4

Ho appena iniziato a studiare sistemi informatici e mi sono imbattuto in questa linea. In che modo la differenza nei contesti in cui vengono visualizzati gli oggetti dati può accadere?

Numeri di negozio dei byte, ora che il numero rappresenta qualcosa, un simbolo o un carattere o qualcos'altro, quindi come può la stessa sequenza di byte rappresentare cose diverse in contesti diversi?

    
posta Pranjal Kumar 06.07.2017 - 18:51
fonte

5 risposte

8

Il modello binario a 8 bit 10000000 (noto come 0x80), può rappresentare:

Anche ottenere il valore come numero richiede un'interpretazione:

Alcuni dei primi computer hanno persino messo i pezzi all'indietro, come nel Manchester Baby sistema informatico sperimentale (del tardo 1940).

Quindi, una data stringa di bit può avere molte interpretazioni diverse. Ogni volta che recuperiamo o gestiamo informazioni consideriamo la dimensione (numero di bit / byte), il modello di bit effettivo (il valore) e tipo , che descrive l'interpretazione di quel modello di bit. In questo modo sappiamo come manipolare le informazioni come poter utilizzare l'aritmetica su un numero o visualizzare una rappresentazione del valore (come simbolo o numero) sullo schermo.

I valori a virgola mobile generalmente utilizzano 4 ( float ) o 8 byte (doppio), anche se ce ne sono altri . L'interpretazione di questi bit utilizza i campi, dividendo i bit in (1) un bit di segno generale, (2) bit di mantissa, (3) un bit di segno esponente e un valore di esponente.

Poiché i byte 4 e 8 sono anche dimensioni comuni per i valori interi, lo stesso valore di 4 byte può essere interpretato come intero o float.

Non c'è modo di esaminare un modello di bit o un valore per sapere quale tipo è destinato , cioè se il valore è inteso come un intero, un float , o un punto di codice o un simbolo o qualcos'altro. Il valore da solo è insufficiente; abbiamo bisogno di qualcosa in più per la differenziazione.

Generalmente lo facciamo al contrario: piuttosto che guardare i bit per indovinare cosa potrebbe essere, noi , come programmatori , comunica al computer come interpretare le informazioni. Pertanto, è in base alla progettazione che sappiamo come interpretare il valore.

Un altro approccio consiste nel taggare un valore usando (alcuni) memoria per un tag o un descrittore; questo consente un'interpretazione dinamica.

È generalmente considerato un errore logico o un difetto nella progettazione del programma o un difetto nella programmazione per interpretare lo stesso valore usando un'interpretazione unica in un punto e la commutazione delle interpretazioni in un altro punto.

In genere i programmi decidono in anticipo come interpretare un dato valore di 4 byte, poiché non è possibile determinarlo in base al valore. Questo fa parte del sistema di tipi di linguaggi di programmazione e, a sua volta, di set di istruzioni per computer.

I sistemi di tipo buono prevengono stati di programmi e errori logici illegali e indesiderati impedendo la combinazione accidentale di interpretazioni e, in generale, questo è un problema molto serio nella programmazione, con molte ricerche attive e continue. Molti sistemi di tipo usano una combinazione di design-time, determinazione del tipo fissa, insieme a qualche forma di tagging per capacità più dinamiche. Alcuni sistemi di tipi funzionano anche a prevenire altri errori logici oltre l'errata interpretazione accidentale, come il riferimento all'array fuori limite, il dereferenziamento del puntatore nullo, le perdite di memoria, la proprietà della memoria, le condizioni di gara, ecc.

Un computer set di istruzioni fornisce in genere diverse istruzioni per manipolare elementi di dimensioni diverse con una varietà di interpretazioni (ad es. come interi con segno , come bit senza segno, come float o double, ecc.). Un linguaggio di programmazione di alto livello utilizza queste varie istruzioni per realizzare l'intento del programma.

    
risposta data 06.07.2017 - 19:53
fonte
0

Come hai detto, il significato di uno specifico pattern di bit dipende dal contesto. Per capire quali dati sono codificati in un particolare pattern di bit, non solo è necessario conoscere lo schema dei bit, ma anche cosa è stato fatto.

Se la posizione di memoria contenente quei dati binari viene passata come indirizzo di un oggetto, allora quei dati sono probabilmente una sorta di puntatore.

Se la memoria viene assegnata a un'istruzione add , probabilmente è un numero.

Se la posizione della memoria è indicata dal contatore del programma, allora è probabilmente un codice OP di istruzioni che doveva essere eseguito dalla CPU.

    
risposta data 06.07.2017 - 19:52
fonte
0

La maggior parte dei linguaggi di programmazione ha un concetto noto come "tipo", implementato tramite un "sistema di tipi".

Quando un programmatore scrive un programma, generalmente dichiara un insieme di variabili e poi scrive un codice sorgente che dice al computer di fare qualcosa con le variabili. Ogni variabile, quando dichiarata, è associata a un tipo, come numero intero, byte o stringa. Il tipo determina come il compilatore interpreterà il codice sorgente che lavora con le variabili, che determinerà quale tipo di codice macchina emettere durante la compilazione.

Ad esempio, in c #, se voglio aggiungere o sottrarre due numeri, potrei scrivere:

int a = 2;
int b = 2;
int c = a + b;
int d = a - b;

In questo codice, ho detto c # che voglio quattro posizioni di memoria e voglio che vengano trattati come numeri interi. Sulla terza riga, posso usare l'operatore + su a e b perché l'aggiunta è consentita per i numeri interi. E sulla quarta riga posso usare - .

Se volessi lavorare con le stringhe, potrei scrivere invece:

string a = "2";
string b = "2";
string c = a + b;
string d = a - b;  //Error

In questo esempio, ho detto c # per impostare quattro posizioni di memoria e trattarle come stringhe. Alla riga 3 posso aggiungerli insieme perché l'aggiunta è valida per le stringhe (le concatenerà). Ma sulla quarta riga il compilatore mi dirà che ho fatto un errore, perché la sottrazione non è consentita per le stringhe, dal momento che non è esattamente chiaro cosa farebbe se fosse permesso.

Allo stesso modo ci sono tipi di dati per date, orari, numeri in virgola mobile e strutture complesse. Inoltre, un programmatore può spesso definire i propri tipi, come oggetti, che possono essere programmati per rappresentare concetti di business, connessioni di database o altre strutture più avanzate, che richiedono una posizione di memoria per l'archiviazione, ma hanno regole diverse per come per leggere quelle posizioni di memoria.

In alcuni rari casi è possibile copiare i dati di un tipo in una variabile di un altro tipo. Questo in genere non è consentito nelle lingue di tipo "sicuro" perché i dati potrebbero essere interpretati erroneamente. Ma in linguaggi come assembly e c, puoi farlo, e di solito devi stare molto attenti a non causare problemi.

Ora che mi dici del codice? Bene, il codice è solo un'altra locazione di memoria, e anch'essa riceve un nome ("simbolo"), noto come punto di ingresso:

static void main()
{
    int a = 2;
    int b = 2;
    int c = a + b;
    int d = a - b;
}

Nell'esempio sopra, dichiaro una posizione di memoria con un punto di ingresso chiamato "main". Questa posizione di memoria conterrà le istruzioni per riservare la memoria per a , b , c e d , e conterrà le istruzioni per impostarle su 2 e per eseguire i calcoli matematici. Quando scrivo codice sorgente che chiama main , il compilatore emetterà un codice leggibile dalla macchina che punta il puntatore all'istruzione al punto di ingresso main , dove eseguirà le istruzioni. Quindi non c'è mai alcun mix tra codice e dati, e il computer (si spera) non tenterà mai di eseguire un numero o provare a fare matematica sul codice.

    
risposta data 06.07.2017 - 19:47
fonte
0

Ben Eater ha una bella serie di video su YouTube in cui crea un computer a 8 bit usando le breadboard . Il risultato è drasticamente semplificato da quello che sembrano i computer di oggi e manca un sacco di cose che è standard al giorno d'oggi, ma i concetti sottostanti sono gli stessi. Nei video, spiega le istruzioni della macchina, gli indirizzi di memoria, la memorizzazione di dati semplici, ecc. E questi valori sono tutti memorizzati come bit in vari registri ed EEPROM.

Gli stessi bit rappresentano cose diverse in base al contesto in cui vivono. Quindi, un valore di 0b0001 significa istruzione LDA ("Carica A", che significa caricare un valore nel registro A) quando quel valore è memorizzato nel registro di istruzioni, ma significa il numero 1 quando memorizzato, ad esempio. C'è un po 'di circonferenza per decodificare l'istruzione LDA in una serie di logiche di controllo che il computer esegue - spostare un valore sul bus, spostare un valore dal bus, ecc.

La chiave per capire questo, IMO, è che a un certo punto tu (come designer / costruttore del computer) arrivi a decidere tutto questo. Non c'è nulla di intrinseco nel valore 0b0001 che significa LDA - è una decisione presa da Ben Eater nei suoi video. Avrebbe potuto facilmente decidere che 0b0101 sarebbe stato LDA, o che 0b0001 sarebbe stata l'istruzione ADD. Anche l'insieme di istruzioni disponibili deve essere deciso, così come gli argomenti per l'istruzione, quante microistruzioni avrà, ecc.

E, come ha detto @ErikEidt nella sua risposta, devi decidere in quale formato i tuoi valori sono memorizzati - non firmati, firmati, a due complementi, a complemento a un altro, ecc. Puoi usare diversi formati per diversi registri o tipi di memoria (probabilmente non è necessario firmare le istruzioni, ad esempio, ma probabilmente si desidera eseguire calcoli che coinvolgono numeri negativi in altre parti del computer). Anche in questo caso, questa è una decisione che prendi quando costruisci il computer.

Una volta che hai tutto ciò, puoi iniziare a crearlo sopra con sistemi operativi, programmi, linguaggi di programmazione, ecc.

    
risposta data 06.07.2017 - 21:46
fonte
0

Al livello più basso (memoria e processore) i byte non rappresentano intrinsecamente nulla (nemmeno i numeri!), sono solo modelli di bit. I byte ottengono solo "significato" nel modo in cui i programmi operano su questi byte.

I processori accettano serie di byte come input per le istruzioni e ogni istruzione interpreta i byte in un modo specifico, ad es.

  • l'istruzione ADD interpreta i byte come numeri interi (dove i bit sono interpretati come cifre binarie) e li aggiunge utilizzando l'aritmetica dei numeri interi.
  • l'istruzione FADD interpreta i byte come numeri in virgola mobile e li aggiunge utilizzando l'aritmetica in virgola mobile (vedi questo per come i numeri in virgola mobile sono rappresentati come bit.)
  • l'istruzione AND tratta i byte come booleani o bit-flags (non numeri!) ed esegue operazioni logiche bit-saggio.
  • l'istruzione MOV copia byte da un posto a un altro e non li interpreta affatto.
  • l'istruzione JMP interpreta i byte come indirizzo di memoria. Ma i byte localizzati in quell'indirizzo di memoria saranno interpretati come istruzioni.

Quindi in breve il codice del programma specifica in che modo i bit sono interpretati come diversi tipi di valori.

    
risposta data 07.07.2017 - 12:36
fonte

Leggi altre domande sui tag