Generazione costanti numeriche

Pubblicità

Matteo34

Nuovo Utente
Messaggi
104
Reazioni
3
Punteggio
45
La mia domanda, potrebbe sembrare banale, ma non riesco proprio a capire come un computer generi una costante numerica, cioè data la seguente istruzione:
Codice:
MOV AX, 4h
Come fa il processore a muovere 4 nel registro AX, quel 4 da dove viene preso e come fa a sapere che 4 equivale proprio a "0000000000000100" a 16bit, come fa a generare questo numero?

Inviato da MI 8 tramite App ufficiale di Tom\'s Hardware Italia Forum
 
La mia domanda, potrebbe sembrare banale, ma non riesco proprio a capire come un computer generi una costante numerica, cioè data la seguente istruzione:
Codice:
MOV AX, 4h
Come fa il processore a muovere 4 nel registro AX, quel 4 da dove viene preso e come fa a sapere che 4 equivale proprio a "0000000000000100" a 16bit, come fa a generare questo numero?

Inviato da MI 8 tramite App ufficiale di Tom\'s Hardware Italia Forum
In ogni processore, vi è una "parte" che si occupa per l'appunto di ciò che chiedi, questa parte cablata in hardware(all'interno della control unit) nei processori moderni è chiamata ISA. L'isa appunto si occupa di interpretare, bada bene, interpretare il linguaggio macchina asm e abilitare le reti richieste. Pertanto:
1)Ha la definizione funzionale del processore, quindi cosa è permesso in hardware, qual'e l'indirizzo dei registri, quei registri quanto son grandi ecc ecc
2)Ne fornisce la precisa descrizione
Che cosa significa?
Ogni istruzione in assembly è composta da varie parti. Una di questi è l' opcode, che identifica l'istruzione scritta, pertanto come immagini è in corrispondenza 1:1 ciò che è cablato nella control unit, si attiva quindi una rete di comparatori che interpreta l'istruzione mov e ne confronta l'opcode con quello memorizzato nella control unit.
come fa a sapere che 4 equivale proprio a "0000000000000100" a 16bit
L'isa che stai considerando è intel, pertanto opera in little endian. I bit di maggior significato si troveranno a destra. per la codifica binaria interviene l'alu( il caso che ti riporto è semplificato) che con una rete di full adder ed invertitori riesce a realizzare la divisione e pertanto la codifica binaria, solitamente questa operazione ha clock 1. Per quanto riguarda il registro AX sempre grazie all'isa si ha direttamente l'indirizzo dello stesso pertanto si crea il dato nel registro selezionato riportando mediante shift register il dato che hai chiesto.
la domanda che hai fatto è tutt'alto che banale, in quanto richiede l'intera comprensione richiede la conoscenza delle reti logiche, e del funzionamento di un processore.
Spero sia tutto chiaro :)
 
Chiarissimo grazie :)
In ogni processore, vi è una "parte" che si occupa per l'appunto di ciò che chiedi, questa parte cablata in hardware(all'interno della control unit) nei processori moderni è chiamata ISA. L'isa appunto si occupa di interpretare, bada bene, interpretare il linguaggio macchina asm e abilitare le reti richieste. Pertanto:
1)Ha la definizione funzionale del processore, quindi cosa è permesso in hardware, qual'e l'indirizzo dei registri, quei registri quanto son grandi ecc ecc
2)Ne fornisce la precisa descrizione
Che cosa significa?
Ogni istruzione in assembly è composta da varie parti. Una di questi è l' opcode, che identifica l'istruzione scritta, pertanto come immagini è in corrispondenza 1:1 ciò che è cablato nella control unit, si attiva quindi una rete di comparatori che interpreta l'istruzione mov e ne confronta l'opcode con quello memorizzato nella control unit.

L'isa che stai considerando è intel, pertanto opera in little endian. I bit di maggior significato si troveranno a destra. per la codifica binaria interviene l'alu( il caso che ti riporto è semplificato) che con una rete di full adder ed invertitori riesce a realizzare la divisione e pertanto la codifica binaria, solitamente questa operazione ha clock 1. Per quanto riguarda il registro AX sempre grazie all'isa si ha direttamente l'indirizzo dello stesso pertanto si crea il dato nel registro selezionato riportando mediante shift register il dato che hai chiesto.
la domanda che hai fatto è tutt'alto che banale, in quanto richiede l'intera comprensione richiede la conoscenza delle reti logiche, e del funzionamento di un processore.
Spero sia tutto chiaro :)

Inviato da MI 8 tramite App ufficiale di Tom\'s Hardware Italia Forum
 
La mia domanda, potrebbe sembrare banale, ma non riesco proprio a capire come un computer generi una costante numerica, cioè data la seguente istruzione:
Codice:
MOV AX, 4h
Come fa il processore a muovere 4 nel registro AX, quel 4 da dove viene preso e come fa a sapere che 4 equivale proprio a "0000000000000100" a 16bit, come fa a generare questo numero?

Inviato da MI 8 tramite App ufficiale di Tom\'s Hardware Italia Forum

Stai dimenticando una cosa molto importante, ovvero quello che hai scritto non è codice macchina, ma assembly!!

Se apri il programma assemblato con un editor esadecimale, noterai che non esiste una singola codifica per MOV, ma ne esistono tante, a seconda della dimensione e del tipo degli operandi. IL 4h non sarà ovviamente scritto così, ma sarà già codificato come stringa di 16 bit. E tutto questo lo fa l'assembler, non il processore.

Al processore arrivano informazioni dettagliate sull'operazione da fare, la tipologia e la dimensione dei due operandi, eventuali operandi immediati ( il 4h ) già codificati opportunamente in una stringa di bit della lunghezza adatta ( 16 in quel caso, perchè la MOV è su AX, che è un registro a 16 bit ).

Esempio banale:

MOV AX, 04h --> 66 b8 04 00
MOV AH, 04h --> b4 04

Come vedi, la codifica è completamente diversa. Eppure abbiamo solo sostituito AX con AH.
 
@Matteo34

A quanto già detto da pabloski e ilfe98, aggiungo solo che se vuoi approfondire la questione puoi iniziare dal manuale dell'8086 di Intel, dove trovi le varie codifiche, e lo puoi trovare qui (l'avevo uppato io): http://www.mediafire.com/download/u4aa3ry00j1545r/231455.zip

Nel caso di MOV:

codifiche.webp

Il campo indicato come "data" rappresenta l'operando di tipo immediato (la costante numerica). Il primo campo che vedi è la codifica dell'istruzione, e il bit "w" indica la dimensione dell'operando (0 = 8bit, 1 = 16bit). Quindi all'interno dell'opcode hai la dimensione degli operandi alla quale fa riferimento pabloski nell'esempio; infatti se w=1 allora è presente il campo data (nei casi dei valori immediati).

Questo da comprendere è più semplice rispetto a IA32/IA64... ma se vuoi guardare cose più attuali, puoi far riferimento al "Software developer manual Vol.2".
A proposito della decodifica, qualche mese fa ho pubblicato questo: MCA.

Se vuoi vedere come vengono codificate rapidamente quelle istruzioni ti conviene generarle "raw" usando NASM (penso sia l'unico o uno dei pochi assembler che te lo consente).
Per fare un esempio pratico:

Codice:
mov  al, 1
mov  ax, 1
mov  eax, 1

Assemblando con:
Codice:
nasm -f bin <nomefile.asm>

Ottieni:
Codice:
B0 01 B8 01 00 66 B8 01 00 00 00

Per capire dove finisce un'istruzione e ne inizia un'altra (a parte il mio MCA) puoi usare un normalissimo editor esadecimale; sotto Windows di solito tengo HxD, ma ne esistono di diversi. Selezionando una parte dei bytes (chiaro, non puoi farlo a caso, devi avere un'idea di ciò che selezioni) ti mostra lo mnemonico (guarda in basso a destra):

hxd.webp

Da notare poi la differenza dell'istruzione che ho selezionato rispetto alle altre (che è quella riportata anche da pabloski): assemblando per 32bit viene aggiunto il byte 0x66, che è un prefisso chiamato "Operand size override prefix". In pratica l'opcode è sempre il medesimo, ma tramite quel prefisso viene fatto l'override di quella che è la dimensione di default (32bit) con 16bit (in quanto il registro di destinazione è a 16bit).
Nota infatti che per la versione con il registro AL l'opcode non è più lo stesso, ma è 0xB0. Puoi far sempre riferimento alla tabella mostrata sopra per 8086: 0xB8 = 10111000b e 0xB0 = 10110000b. E' stata usata la versione più compatta senza modregrm che ha la forma 1011 w reg. A questo punto noterai che 0xB8 ha proprio il bit w=1, che è quello che fa anche estendere il numero ("data", il valore immediato); giusto a titolo informativo: reg identifica proprio il registro di destinazione.

Un pò come avviene per l'altra forma (8/16bit), se usi RAX (64bit) con un numero abbastanza grande come 0x123456789 (>32bit, altrimenti verrà utilizzato eax molto probabilmente), viene generato:
Codice:
48 B8 89 67 45 23 01 00 00 00

Dove 0x48 è un altro prefisso (REX prefix), 0xB8 è sempre l'opcode di prima. L'altro è il numero espresso come sempre usando little endian; nota che è stato esteso con 3byte a 0, venendo trattato come 64bit.

Ho forse sconfinato un pò troppo dalla domanda, ma spero sia comunque chiaro...
 
Grazie a tutti :)
@Matteo34

A quanto già detto da pabloski e ilfe98, aggiungo solo che se vuoi approfondire la questione puoi iniziare dal manuale dell'8086 di Intel, dove trovi le varie codifiche, e lo puoi trovare qui (l'avevo uppato io): http://www.mediafire.com/download/u4aa3ry00j1545r/231455.zip

Nel caso di MOV:

Visualizza allegato 403433

Il campo indicato come "data" rappresenta l'operando di tipo immediato (la costante numerica). Il primo campo che vedi è la codifica dell'istruzione, e il bit "w" indica la dimensione dell'operando (0 = 8bit, 1 = 16bit). Quindi all'interno dell'opcode hai la dimensione degli operandi alla quale fa riferimento pabloski nell'esempio; infatti se w=1 allora è presente il campo data (nei casi dei valori immediati).

Questo da comprendere è più semplice rispetto a IA32/IA64... ma se vuoi guardare cose più attuali, puoi far riferimento al "Software developer manual Vol.2".
A proposito della decodifica, qualche mese fa ho pubblicato questo: MCA.

Se vuoi vedere come vengono codificate rapidamente quelle istruzioni ti conviene generarle "raw" usando NASM (penso sia l'unico o uno dei pochi assembler che te lo consente).
Per fare un esempio pratico:

Codice:
mov al, 1
mov ax, 1
mov eax, 1

Assemblando con:
Codice:
nasm -f bin

Ottieni:
Codice:
B0 01 B8 01 00 66 B8 01 00 00 00

Per capire dove finisce un'istruzione e ne inizia un'altra (a parte il mio MCA) puoi usare un normalissimo editor esadecimale; sotto Windows di solito tengo HxD, ma ne esistono di diversi. Selezionando una parte dei bytes (chiaro, non puoi farlo a caso, devi avere un'idea di ciò che selezioni) ti mostra lo mnemonico (guarda in basso a destra):

Visualizza allegato 403436

Da notare poi la differenza dell'istruzione che ho selezionato rispetto alle altre (che è quella riportata anche da pabloski): assemblando per 32bit viene aggiunto il byte 0x66, che è un prefisso chiamato "Operand size override prefix". In pratica l'opcode è sempre il medesimo, ma tramite quel prefisso viene fatto l'override di quella che è la dimensione di default (32bit) con 16bit (in quanto il registro di destinazione è a 16bit).
Nota infatti che per la versione con il registro AL l'opcode non è più lo stesso, ma è 0xB0. Puoi far sempre riferimento alla tabella mostrata sopra per 8086: 0xB8 = 10111000b e 0xB0 = 10110000b. E' stata usata la versione più compatta senza modregrm che ha la forma 1011 w reg. A questo punto noterai che 0xB8 ha proprio il bit w=1, che è quello che fa anche estendere il numero ("data", il valore immediato); giusto a titolo informativo: reg identifica proprio il registro di destinazione.

Un pò come avviene per l'altra forma (8/16bit), se usi RAX (64bit) con un numero abbastanza grande come 0x123456789 (>32bit, altrimenti verrà utilizzato eax molto probabilmente), viene generato:
Codice:
48 B8 89 67 45 23 01 00 00 00

Dove 0x48 è un altro prefisso (REX prefix), 0xB8 è sempre l'opcode di prima. L'altro è il numero espresso come sempre usando little endian; nota che è stato esteso con 3byte a 0, venendo trattato come 64bit.

Ho forse sconfinato un pò troppo dalla domanda, ma spero sia comunque chiaro...

Inviato da MI 8 tramite App ufficiale di Tom\'s Hardware Italia Forum
 
Molto banalmente, si chiama in genere sezione ".text" la parte dove la tua costante sara' scritta. In poche parole, viene scritta proprio dentro al tuo .exe, ecco ome il processore lo sa, perche la legge dalla stessa memoria da dove vengono lette le istruzioni del programma.
 
Pubblicità
Pubblicità
Indietro
Top