PDA

View Full Version : [assembly] architettura IA-32


misterx
22-04-2009, 21:29
siccome non trovo un piffero da nessuna parte vi chiedo: nei processori intel esistono registri specifici solo per le istruzioni e registri specifici solo per i dati ?

cdimauro
22-04-2009, 21:42
Francamente non capisco bene la domanda. Potresti cortesemente provare a formularla in maniera più chiara? Grazie.

misterx
22-04-2009, 22:36
Francamente non capisco bene la domanda. Potresti cortesemente provare a formularla in maniera più chiara? Grazie.

a me sembra chiara a sufficienza :)

cdimauro
23-04-2009, 08:04
In tal caso, mi spiace, ma non potrò fornirti nessuna risposta.

misterx
23-04-2009, 09:59
In tal caso, mi spiace, ma non potrò fornirti nessuna risposta.

un esperto di assembly saprebbe dirmi se codice e dati finisconon nello stesso registro oppure codice e dato finiscono in registri separati :)

71104
23-04-2009, 10:13
a me sembra chiara a sufficienza :) non lo era affatto


un esperto di assembly saprebbe dirmi se codice e dati finisconon nello stesso registro oppure codice e dato finiscono in registri separati :) non lo é neanche adesso, non ha senso: codice e dati stanno in memoria (come in tutte le macchine di Von Neumann) e i registri possono contenere qualunque cosa venga presa dalla memoria.

misterx
23-04-2009, 10:18
non lo era affatto


non lo é neanche adesso, non ha senso: codice e dati stanno in memoria (come in tutte le macchine di Von Neumann) e i registri possono contenere qualunque cosa venga presa dalla memoria.

nell'architettura IA-32, a meno che non abbia inteso male io si legge che il registro CS = code segment (quindi ci dovrebbero andare solo istruzioni) ed il registro DS = data segment (qui ci vanno solo dati=parametri), tralasciando gli altri per non complicare le cose.

Il mio dubbio nasce dal fatto che se il PC (program counter) che tiene traccia del prossimo indirizzo da leggere fa mettere nel registro CS un dato qualsiasi e non una istruzione, come fa la cpu ad eseguirla ?

Dovrebbe avere un registro specifico dove eseguire le istruzioni con parametri presenti in un altro registro: sbaglio ?

cdimauro
23-04-2009, 11:07
nell'architettura IA-32, a meno che non abbia inteso male io si legge che il registro CS = code segment (quindi ci dovrebbero andare solo istruzioni) ed il registro DS = data segment (qui ci vanno solo dati=parametri), tralasciando gli altri per non complicare le cose.
No, il CS indica soltanto un segmento. Poi nel segmento è possibile memorizzare anche dati, oltre a istruzioni.

Lo stesso vale per qualunque altro registro, DS incluso.

Anzi, è possibile scrivere applicazioni per cui CS = DS = ES = SS, ad esempio.
Il mio dubbio nasce dal fatto che se il PC (program counter) che tiene traccia del prossimo indirizzo da leggere fa mettere nel registro CS un dato qualsiasi e non una istruzione, come fa la cpu ad eseguirla ?

Dovrebbe avere un registro specifico dove eseguire le istruzioni con parametri presenti in un altro registro: sbaglio ?
C'è un po' di confusione. CS punta soltanto a un segmento. Poi in coppia con IP il processore compone l'indirizzo dell'istruzione da eseguire.

Se viene caricata un'istruzione non valida, viene generata un'eccezione coi processori moderni (con quelli vecchi no).

Questo se ho capito bene il tuo dubbio.

misterx
23-04-2009, 11:26
No, il CS indica soltanto un segmento. Poi nel segmento è possibile memorizzare anche dati, oltre a istruzioni.

Lo stesso vale per qualunque altro registro, DS incluso.

Anzi, è possibile scrivere applicazioni per cui CS = DS = ES = SS, ad esempio.

C'è un po' di confusione. CS punta soltanto a un segmento. Poi in coppia con IP il processore compone l'indirizzo dell'istruzione da eseguire.

Se viene caricata un'istruzione non valida, viene generata un'eccezione coi processori moderni (con quelli vecchi no).

Questo se ho capito bene il tuo dubbio.

ti correggo, ho molta confusione non poca :stordita:

Mi sa che questa discussione non andava in questo spazio, pardon!

gugoXX
23-04-2009, 11:43
Diciamo che molti registri, come ad esempio i selettori di segmento, non vanno bene per essere usati per dati utente.
Intendo, se devo effettuare l'operazione 3+5, i valori 3 e 5 possono essere messi in tanti registri che potranno essere usati come sorgente per la somma, ma sicuramente non andro' a metterli in registri di tipo selettore.
Ci sono poi tanti registri, ciascuno con le sue caratteristiche, che NON potranno similmente servire allo scopo, come GDT, IDT.
Altri registri sono invece readonly, e quindi a maggior ragione non potranno essere usati.
Anche la parola di stato, i flag, sono in un registro, e anche questo non potra' essere usato per dati utente.
Ci sono poi registri che seppure possano essere usati per dati utente, non verranno usati allo scopo, come ESP e EBP, usati normalmente per operazioni sullo stack, e addirittura implicitamente coinvolti nelle operazioni assembly che operano appunto sullo stack.

"Registri solo per le istruzioni" e' un po' stiracchata come definizione, e mi sentirei di dire che solo il registro selettore CS e il registro del Program Counter EIP sono gli unici che hanno effettivamente a che fare SOLO con le istruzioni e che non vengono effettivamente usati per nient'altro.

Diciamo quindi che ci sono registri che possono essere usati per memorizzare/trattare dati, e registri che invece non si usano per questo, sebbene nessuno mi vieti di memorizzare 5 per la somma 5+7 nel registro TR3 o in DR2, il primo usato durante le procedure di self-test e il secondo che e' uno dei registri usati in modailita' DEBUG (step-by-step) del microprocessore, e il cui significato e' "Solleva un interrupt (ben specifico) quando il registro EIP (o forse l'inidirizzo fisico vero, non ricordo) arriva a valere il valore contenuto nel registro DRn"
Fatto salvo che poi questo registro non potro' usarlo come sorgente per una somma, e fatto salvo che non sia in modalita' DEBUG quando presumibilmente tale registro potrebbe servirmi e cambiarlo potrebbe dare effetti poco predicibili, nulla mi vieta di usarlo come "contenitore" temporaneo per dei dati.
Ma e' direi controproducente, dato che scrivere in tali registri e' normalmente addirittura piu' lento che scrivere in una cella di RAM.

cdimauro
23-04-2009, 11:51
Già era confuso prima, adesso gli hai dato il colpo di grazia. :asd:

misterx
23-04-2009, 11:55
"Registri solo per le istruzioni" e' un po' stiracchata come definizione, e mi sentirei di dire che solo il registro selettore CS e il registro del Program Counter EIP sono gli unici che hanno effettivamente a che fare SOLO con le istruzioni e che non vengono effettivamente usati per nient'altro.


quindi i registri CS,DS,SS etc.. sono ad uso esclusivo della CPU ?

Ora ricordo che la memoria viene segmentata e ogni segmento contiene codiece/dati/stack, quandi tali registri si riferiscono a questi segmenti di memoria....se non ricordo male

Comunque, grazie 1000 per le vostro risposte

gugoXX
23-04-2009, 11:56
Già era confuso prima, adesso gli hai dato il colpo di grazia. :asd:

Ho paura di si'.
Forse sarebbe utile studiare cosa e' un registro, cosa sono i dati, cosa sono le istruzioni e come fa una macchina ad eseguire le istruzioni.
Ovvero Von Neumann capitolo 1

misterx
23-04-2009, 11:56
Già era confuso prima, adesso gli hai dato il colpo di grazia. :asd:

tranquillo che recupero in fretta :D

ci vuole ben altro....dopo aver passato statistica, almeno questa (cpu, registri et similia) è informatica ed è divertente ;)

cmq, ho trovato qualcosa http://it.wikipedia.org/wiki/Architettura_di_un_processore_basato_su_registri_generali

misterx
23-04-2009, 12:23
Ho paura di si'.
Forse sarebbe utile studiare cosa e' un registro, cosa sono i dati, cosa sono le istruzioni e come fa una macchina ad eseguire le istruzioni.
Ovvero Von Neumann capitolo 1

non devo entrare troppo nel dettaglio :)
Architetture l'ho dato qualche annetto fa!

gugoXX
23-04-2009, 12:46
Beh, allora andare avanti solo con definizioni non so se ti aiutera'.
Questo perche' per esempio non esistono registri utente che in alcun istante contengono "istruzioni". Non esistono quindi registri prettamente per le "istruzioni".
I registri che contengono le istruzioni che vengono eseguite in un determinato istante non sono registri accessibili dall'esterno del microprocessore, e nemmeno vengono comunemente chiamati registri.

Pensa poi al fatto che l'immagine binaria di un'istruzione e' di poco aiuto per il core del microprocessore Intel (e AMD), essendo che i Core2 sono microprogrammati, ovvero ogni singola istruzione macchina viene convertita in altre microistruzioni macchina. Ogni istruzione e' in realta' un programmino che fa uso di registri macchina non accessibili all'esterno.
Addirittura i Motorola (almeno fino al 68030) sono nanoprogrammati.
Ogni istruzione macchina dell'assembly dei motorola viene convertita in una o piu' microistruzioni. Ogni microistruzione e' a sua volta un nanoprogramma, composto da una o piu' nanoistruzioni. Nessuna delle celle di memoria interne del motorola che viene caricata in un determinato istante con una nanoistruzione del nanoprogramma e' accessibile all'esterno ne' in lettura ne' in scrittura.

Quindi puoi caricare se vuoi quello che e' il contenuto binario di un'istruzione in un registro utente, ma questo non servira' al processore per eseguirla, ne si puo' dire che possa servire per le istruzioni.

Parziale controesempio: WinZip e in generale programmi di compressione/decompressione.
Se io decomprimo un eseguibile ovviamente sto creando in memoria un bulk di dati che POI, forse, saranno un programma che verra' eseguito.
Durante l'esecuzione del decompressore (ma anche del compressore) quindi ci sara' un istante in cui qualcuno dei registri del microprocessore conterra' un'istruzione macchina. Ma per lui in quel momento non sono altro che dati agnostici. Per il decompressore e il microprocessore tali contenuti non sono altro che dati come tutti gli altri, e il fatto che possano essere in realta' istruzioni di un programma non aiutera' o non provochera' l'esecuzione di alcunche'. Che sia una immagine o un esegubilie, non si puo' dire che alcun registro in alcun istante contenga istruzioni per il microprocessore, ove per istruzione si intende qualcosa che viene caricato in qualunque registro per essere effettivamente "eseguito"

misterx
23-04-2009, 16:45
Beh, allora andare avanti solo con definizioni non so se ti aiutera'.

a noi al corso di SO hanno suggerito di leggere le prime 10 pagine dei primi 6 capitoli del manuale di intel

"Intel® 64 and IA-32 Architectures
Software Developer’s Manual
Volume 3A:
System Programming Guide, Part 1"

e lasciato tutto il resto per chi desidera approfondire, ovviamente tempo permettendo.

Lo scopo del corso di SO che sto seguendo io è capire come lavora/ragiona minix su piattaforma intel, per questo motivo mi servono i rudimenti di come lavora intel. E' già impegnativo studiare i vari algoritmi di scheduling e quant'altro che non ci sarebbe modo di approfondire più di tanto, forse più in là.

Allo stato attuale mi interessa capire dove e come scrivo nella cpu attraverso l'assembly: scrivere mov eax,xyz opure push 1 senza capire dove finiscono i dati non mi è sufficiente.
Siccome nel corso si citano differenti registri della CPU è interessante capire come sono fatti e come lavorano ma senza entrare nel dettaglio di come lavora l'ALU, MAR etc...

Comunque grazie infinite per i vostri interventi

Tesinevb
23-04-2009, 17:42
a noi al corso di SO hanno suggerito di leggere le prime 10 pagine dei primi 6 capitoli del manuale di intel

"Intel® 64 and IA-32 Architectures
Software Developer’s Manual
Volume 3A:
System Programming Guide, Part 1"

e lasciato tutto il resto per chi desidera approfondire, ovviamente tempo permettendo.

Lo scopo del corso di SO che sto seguendo io è capire come lavora/ragiona minix su piattaforma intel, per questo motivo mi servono i rudimenti di come lavora intel. E' già impegnativo studiare i vari algoritmi di scheduling e quant'altro che non ci sarebbe modo di approfondire più di tanto, forse più in là.

Allo stato attuale mi interessa capire dove e come scrivo nella cpu attraverso l'assembly: scrivere mov eax,xyz opure push 1 senza capire dove finiscono i dati non mi è sufficiente.
Siccome nel corso si citano differenti registri della CPU è interessante capire come sono fatti e come lavorano ma senza entrare nel dettaglio di come lavora l'ALU, MAR etc...

Comunque grazie infinite per i vostri interventi

Vai quì:
http://xoomer.virgilio.it/ramsoft/

banryu79
23-04-2009, 17:51
Vai quì:
http://xoomer.virgilio.it/ramsoft/
Mitica fonte :ave:

misterx
23-04-2009, 18:42
Vai quì:
http://xoomer.virgilio.it/ramsoft/


lo stò leggendo, grazie :)

Per me è stato fondamentale il capitolo 9

misterx
23-04-2009, 20:01
da quanto ne ho capito, intel segmenta la memoria ram in un certo numero di segmenti. Quando si esegue un programma, le istruzioni vengonon copiate in un segmento ed i dati in un altro segmento.
Quindi i registri CS e DS contengono l'indirizzo di questi due segmenti. Ipotizzo ora che se viene letto dalla CPU una istruzione che prevede due operandi, si va nel segmento dei dati e si prelevano due dati e così via. Ovviamente ogni volta si incrementa il PC per conoscere la prossima istruzione da eseguire.
Detto alla spicciolata ma il concetto dovrebbe essere questo, giusto ? :)

71104
23-04-2009, 21:07
da quanto ne ho capito, intel segmenta la memoria ram in un certo numero di segmenti. Quando si esegue un programma, le istruzioni vengonon copiate in un segmento ed i dati in un altro segmento.
Quindi i registri CS e DS contengono l'indirizzo di questi due segmenti. Ipotizzo ora che se viene letto dalla CPU una istruzione che prevede due operandi, si va nel segmento dei dati e si prelevano due dati e così via. Ovviamente ogni volta si incrementa il PC per conoscere la prossima istruzione da eseguire.
Detto alla spicciolata ma il concetto dovrebbe essere questo, giusto ? :) sarebbe stato giusto fino a vent'anni fa, nell'epoca dei 16 bit e della transizione ai 32 bit; oggi di norma i sistemi operativi schiaffano codice e dati di ogni processo nello stesso segmento (nello specifico Windows utilizza in maniera effettiva la segmentazione solo nelle transizioni tra kernel mode e user mode, che significa che il kernel space sta in un segmento diverso dallo user space ma per il resto tutti i processi stanno nello stesso segmento).
fai un esperimento: scrivi un programma a 32 bit che ti stampa sullo standard output il contenuto dei registri CS e DS (e anche ES se vuoi); dovrebbero essere tutti uguali e non dovrebbero cambiare neanche riavviando il programma piu volte; la cosa non funziona nei programmi a 16 bit, i quali invece girano in modalitá virtuale x86 e quindi usano il vecchio sistema di segmentazione (quello di vent'anni fa di cui parlavo prima).

misterx
23-04-2009, 21:25
sarebbe stato giusto fino a vent'anni fa, nell'epoca dei 16 bit e della transizione ai 32 bit; oggi di norma i sistemi operativi schiaffano codice e dati di ogni processo nello stesso segmento (nello specifico Windows utilizza in maniera effettiva la segmentazione solo nelle transizioni tra kernel mode e user mode, che significa che il kernel space sta in un segmento diverso dallo user space ma per il resto tutti i processi stanno nello stesso segmento).
fai un esperimento: scrivi un programma a 32 bit che ti stampa sullo standard output il contenuto dei registri CS e DS (e anche ES se vuoi); dovrebbero essere tutti uguali e non dovrebbero cambiare neanche riavviando il programma piu volte; la cosa non funziona nei programmi a 16 bit, i quali invece girano in modalitá virtuale x86 e quindi usano il vecchio sistema di segmentazione (quello di vent'anni fa di cui parlavo prima).


quindi hanno trovato un metodo per nella mischia di trovare istruzioni e dati ? :stordita:

71104
23-04-2009, 22:28
quindi hanno trovato un metodo per nella mischia di trovare istruzioni e dati ? :stordita: ricominci ad essere incomprensibile per me.

misterx
24-04-2009, 05:56
ricominci ad essere incomprensibile per me.

ok, scusa: torno a parlare in modo scolastico :D
Se non ho capito male, 20 anni fa i byte che rappresentavano il programma venivano memorizzati in un segmento mentre i byte che rappresentavano i dati venivano memorizzati in un altro segmento, DS e CS poi contenevano gli indirizzi ai rispettivi segmenti.
Oggi le cose non stanno più così, da quanto ho appreso la memoria viene ancora frammentata ma codice e dati non sono più mantenuti separati ma sono nello stesso segmento: mi chiedo come fa il processore a determinare quale sequenza di byte rappresenta un dato e quale un dato.

Intuitivamente mi viene in mente che forse in fase di compilazione, codice e dati vengono intercalati in modo opportuno in quanto il processore se li aspettain questo modo: ma è solo una ipotesi.

71104
24-04-2009, 16:40
premessa: i files esegubili (sia quelli di Windows, formato PE, sia quelli di Linux, formato ELF) sono divisi in parti dette "sezioni" che ricordano vagamente i segmenti dell'architettura Intel; comunque, come abbiamo detto, su Windows quando un file eseguibile viene caricato in memoria virtuale tutte le sue sezioni stanno nello stesso segmento x86, cosi come le sezioni di qualunque altro programma eseguibile in esecuzione in qualunque altro processo. fine premessa.

tanto per cominciare esistono diversi tipi di dati: i dati globali, i dati allocati in memoria automatica e i dati allocati dinamicamente in un heap.

i dati globali sono le variabili che in C/C++ dichiari nello scope globale oppure nello scope di una funzione ma usando il modificatore static; questi dati vengono si suddividono a loro volta in dati inizializzati e non: le variabili inizializzate vengono allocate in fase di compilazione in una apposita sezione dell'eseguibile che di norma su Windows (eseguibili PE) si chiama ".idata" o ".rdata" (".rdata" é per le variabili a sola lettura); le variabili non inizializzate invece vengono allocate "virtualmente" in un'altra sezione dell'eseguibile (".data" nei file PE) che ha dimensione nulla sul file fisico e dimensione non nulla in memoria virtuale: quando Windows mappa in memoria il file eseguibile alloca la dimensione richiesta per la sezione ".data" e la riempie di zeri.

i dati allocati in memoria automatica sono quelli allocati sullo stack, anche detta memoria automatica grazie al fatto che tali dati vengono deallocati automaticamente non appena vanno fuori scope; ad esempio una variabile intera dichiarata localmente in una funzione (senza il modificatore static) viene deallocata non appena l'esecuzione della funzione termina.
lo stack (o gli stack, visto che ogni thread ha il suo) viene gestito da Windows con un semplice meccanismo basato sul virtual memory manager; il virtual memory manager permette di allocare pagine di memoria virtuale e anche di riservarne altre per possibili allocazioni future. quando il subsystem Win32 deve allocare uno stack per un thread non fa altro che richiedere l'allocazione di una pagina di memoria virtuale e il reserve di altre N-1 pagine immediatamente seguenti, dove N viene definito in fase di linking (solitamente i programmi hanno 1 MB di stack per ogni thread e inizialmente di questo MB solo i primi 4 KB, cioé la prima pagina, sono effettivamente allocati); ti risparmio i dettagli su cosa accade quando lo stack di un thread cresce oltre la prima pagina (se ti interessa studiati i page guards).

infine ci sono i dati allocati dinamicamente in un heap, che sono quelli che in C allochi con malloc o calloc e in C++ con new. un programma Win32 puó avere zero o piu heaps che sono gestiti dall'heap manager di Windows, anch'esso basato sul virtual memory manager. ciascun heap permette di allocare dinamicamente blocchi di memoria virtuale di dimensione arbitraria; l'heap manager implementa gli algoritmi necessari a far funzionare un simile sistema al di sopra del virtual memory manager, il quale ha una differenza fondamentale dall'heap manager: permette di allocare blocchi di dimensione non arbitraria, bensi multipla di 4 KB. ti risparmio i dettagli sul problema della frammentazione, che viene risolto dai runtime C e C++ di Visual C++ implementati al di sopra dell'heap manager di Windows.

questo é il contesto generale e ti dovrebbe dare un'idea piu precisa di come vivono i diversi tipi di dati all'interno di un programma per Windows, considerando che su Linux la situazione é del tutto analoga. ora, cosa vorresti sapere? leggendo questa frase:

"mi chiedo come fa il processore a determinare quale sequenza di byte rappresenta un dato e quale un dato."

immagino di poterla reinterpretare in questo modo:

"mi chiedo come fa il processore a determinare quale sequenza di byte rappresenta un dato e quale un istruzione."

ma non capisco perché secondo te il processore dovrebbe avere il bisogno di determinare questa cosa; che intendi con "determinare"?

misterx
24-04-2009, 21:50
ma non capisco perché secondo te il processore dovrebbe avere il bisogno di determinare questa cosa; che intendi con "determinare"?

la risposta me la hai già data dicendomi che i dati vengono disposti in un certo modo in fase di compilazione.

Con "determinare" intendevo tale fatto: se penso a quando i dati e le istruzioni venivano mantenute in segmenti separati mi vinene facile pensare come la cpu potesse accedere solo ad istruzioni e non a dati in quanto aveva un'area di memoria specifica.
Se ora i dati stanno nello stesso segmento, mi chiedevo come facesse la cpu a capire quale byte rappresenta un dato e quale una istruzione, banalmente: D8 potrebbe essere sia un dato che una istruzione.

Comunque hai risolto il mo dubbio dicendomi che il compilatore posiziona i dati in un certo modo e quindi esiste una sorta di accordo tra la cpu ed il software: queso per dirla alla mia maniera :)

grazie 1000 per l'approfondimento

71104
24-04-2009, 23:57
in realtá l'accordo non coinvolge la CPU; la CPU, molto ignorantemente, non fa altro che seguire il flusso di codice, va dove la portano le istruzioni; poi chiaramente il codice dell'eseguibile é fatto in maniera tale da non portarla nelle zone di memoria contenenti dati, a meno che quella non sia la specifica intenzione del programmatore.

Tesinevb
25-04-2009, 01:13
[QUOTE=misterx;27214792]...mi chiedo come fa il processore a determinare quale sequenza di byte rappresenta un dato e quale un dato...
QUOTE]

E' scritto nel capitolo 11...

11.2.3 Campo Opcode: con i codice mnemonici il computer capisce se si tratta di un istruzione o un dato

per l'altra domanda... 20 anni fà l'architettura era a 16 bit poi con pc + nuovi aumentarono il bus address a 20 linee e gli ingegneri ebbero il colpo di genio di indirizzare 1 mb prendendolo con lo spiazzamento dell'offset il +10 andano all'altro paragrafo su architettura a 16 bit... questo fece in modo che i programmi potessero girare su tutti i pc in commercio dell'epoca

misterx
25-04-2009, 07:34
[QUOTE=misterx;27214792]...mi chiedo come fa il processore a determinare quale sequenza di byte rappresenta un dato e quale un dato...
QUOTE]

E' scritto nel capitolo 11...

11.2.3 Campo Opcode: con i codice mnemonici il computer capisce se si tratta di un istruzione o un dato

per l'altra domanda... 20 anni fà l'architettura era a 16 bit poi con pc + nuovi aumentarono il bus address a 20 linee e gli ingegneri ebbero il colpo di genio di indirizzare 1 mb prendendolo con lo spiazzamento dell'offset il +10 andano all'altro paragrafo su architettura a 16 bit... questo fece in modo che i programmi potessero girare su tutti i pc in commercio dell'epoca



grazie.

Difatti stavo leggendo la struttura ad esempio di una istruzione 80386 dove ogni byte o gruppo di byte rappresentano informazioni diverse per la cpu.
Se ho contato bene, la struttura è ambia 16 byte, quindi sia che usi o non usi certi byte, la dimensione rimane sempre di 16 byte, un esempio in questa (http://books.google.it/books?id=hK8lJ4BPOYcC&pg=PA348&lpg=PA348&dq=struttura+istruzione+pentium+opcode&source=bl&ots=yQEefq9vOH&sig=1mMiSDHumzVwK5_PyIl_G5-W3v8&hl=it&ei=FrHySfqAF82D_QbRopnVCQ&sa=X&oi=book_result&ct=result&resnum=1#PPA348,M1) pagina in basso dove i campi che si notano sono fissi.
Ricorda molto una struct del C.

cdimauro
25-04-2009, 08:15
Assolutamente no. La famiglia x86 è costituita da microprocessori CISC, che notoriamente utilizzano opcode a lunghezza variabile.

16 byte è la dimensione massima che può avere un opcode, ma la minima è costituita da 1 solo byte.

Soltanto i RISC hanno opcode a lunghezza fissa, ma il "taglio" in genere è 16 o 32bit, quindi 2 o 4 byte.

Esistono poi delle varianti dei RISC, chiamati VLIW, che hanno opcode a lunghezza fissa ma di notevole dimensione. Questo perché, in realtà, codificano PIU' istruzioni nello stesso opcode, che vengono eseguite tutte in una volta.
Esempi ne sono l'Itanium di Intel, che ha opcode di 128 bit (16 byte, contenenti 3 istruzioni), o l'Efficeon della defunta Transmeta, che addirittura aveva opcode di 256 bit (32 byte, contenenti 8 istruzioni).

misterx
25-04-2009, 08:24
Assolutamente no. La famiglia x86 è costituita da microprocessori CISC, che notoriamente utilizzano opcode a lunghezza variabile.

16 byte è la dimensione massima che può avere un opcode, ma la minima è costituita da 1 solo byte.

Soltanto i RISC hanno opcode a lunghezza fissa, ma il "taglio" in genere è 16 o 32bit, quindi 2 o 4 byte.

Esistono poi delle varianti dei RISC, chiamati VLIW, che hanno opcode a lunghezza fissa ma di notevole dimensione. Questo perché, in realtà, codificano PIU' istruzioni nello stesso opcode, che vengono eseguite tutte in una volta.
Esempi ne sono l'Itanium di Intel, che ha opcode di 128 bit (16 byte, contenenti 3 istruzioni), o l'Efficeon della defunta Transmeta, che addirittura aveva opcode di 256 bit (32 byte, contenenti 8 istruzioni).

ah ecco, al link che mi è stato fornito non si parlava di campi opzionali!

71104
25-04-2009, 10:03
per l'altra domanda... 20 anni fà l'architettura era a 16 bit poi con pc + nuovi aumentarono il bus address a 20 linee e gli ingegneri ebbero il colpo di genio di indirizzare 1 mb prendendolo con lo spiazzamento dell'offset il +10 andano all'altro paragrafo su architettura a 16 bit... questo fece in modo che i programmi potessero girare su tutti i pc in commercio dell'epoca misterx, dimentica questa roba: é tutto sbagliato

cdimauro
25-04-2009, 10:49
http://www.appuntidigitali.it/3044/8086-bizzarrie-di-unarchitettura-dominante/ ;)

misterx
25-04-2009, 13:15
se alcuni campi sono opzionali, come fa la cpu e trovare le istruzioni ?

Forse il mio dubbio nasce dal fatto che on ho ancora letto come vengonon organizzate le istruzioni e i dati nella RAM.

cdimauro
25-04-2009, 13:29
Non è un problema insormontabile, anzi. Leggi il primo byte, vedi quali informazioni si porta dietro, e in base a queste capisci se ti servono altri byte. Li leggi, e continui finché non ti è chiaro cosa devi fare.

Questo dal punto di vista del decoder delle istruzioni della CPU.

StateCity
25-04-2009, 14:03
siccome non trovo un piffero da nessuna parte vi chiedo: nei processori intel esistono registri specifici solo per le istruzioni e registri specifici solo per i dati ?
La domanda e' perfettamente pertinente ! :D

il "guaio" e' che anche x i programmatori piu' esperti oramai l'assembler (o assembly nn sottilizziamo.. :asd: )
lo considerano superato, e questo e' un errore fatale ! :asd:

In breve l'architettura x86 ha :
4 registri dati a 16 bit (AX, BX, CX, DX)
4 registri punatori e indici a 16 bit (SP, BP, SI, DI)
4 registri di segmento a 16 bit (CS, DS, SS, ES)

oltre ad altri registri interni, come IP e il FLAG

Ogni registro puo' essere utilizzato per contenere dati generali..
ma solo alcuni sono abilitati per funzioni particolari.. :D
ad esempio IMUL utilizza come destinazione solo il registro AX
oppure LODSW indirizza solo il dato puntato da SI e lo trasferisce in AX
e non puo' utilizzare direttamente altri registri..

http://en.wikipedia.org/wiki/X86

bye :)

StateCity
25-04-2009, 14:12
qualche aggiunta... :rolleyes:

I registri generali si utilizzano principalmente per contentere dati e fare elaborazione numerica..
I registri puntatori si utilizzano principalmente per memorizzare la parte bassa (offset)
delle locazioni di memoria..
(e in questi, solo il registro SP e' dedicato ad indicizzare lo stack pointer..)
I registri segmento si utilizzano principalmente per memorizzare la parte alta (segment) delle locazioni di memoria..
(e in questi, il registro CS e' dedicato esclusivamente ad indirizzare il segmento di il codice.. da non toccare assolutamente.. )

Poi volendo e' anche possibile memorizzare un dato numerico in ES,
ma sarebbe meglio utilizzare i registri solo per la loro naturale destinazione d'uso,
evitando di fare confusioni e programmi illegibili.. :rolleyes:

bye.. :)

misterx
25-04-2009, 16:59
mi rimane il dubbio se è la cpu che vede la memoria segmentata oppure è l'SO a segmentarla.

Dico questo perchè ho provato a compilare un programma in C e visualizzare col debugger il corrispettivo codice assembly. Di fatto vedo il contenuto di tutti i registri della CPU e mi aspettavo che eseguendo il programma passo passo, il valore di CS, DS ed SS cambiasse invece rimane fisso.

Mi chiedo se questo comportemtno è dovuto al fatto che:

a) i segmenti sono di dimensione variabile e quindi il compilatore crea una zona di memoria che non verrà mai esaurita nel senso che, il mio programma non userà mai un altro segmento e quindi, non vedo cambiare i registri CS, DS,SS

b) il segmento è fisso ma il mio programma è di dimensioni talmente ridotte che sta comodamente in un segmento e per questo non vedo nessuna variazione

c) le variazioni dei registri DS, CS, SS li vedrei sse debugassi l'SO e non un mio programma

cdimauro
25-04-2009, 17:09
Se hai realizzato un'applicazione a 32 bit, allora non hai più segmenti, ma selettori.

Inoltre, come diceva "71104", il modello utilizzato nei moderni s.o. è "flat", ovvero tutti i segmenti sono caricati con lo stesso valore, perché ormai non si usa più la segmentazione per suddividere codice, dati, e stack, ma la paginazione è il modello standard.

I selettori hanno ormai fatto il loro tempo, tant'è che nell'evoluzione a 64 bit (AMD64 o x86-64 che dir si voglia) sono praticamente spariti nella modalità nativa (a 64 bit, appunto), in quanto l'unico modello a disposizione è quello paginato (questo non è del tutto vero perché FS e GS sono utilizzati dal s.o., ma dal punto di vista applicativo è tutto paginato).

StateCity
25-04-2009, 17:44
mi rimane il dubbio se è la cpu che vede la memoria segmentata oppure è l'SO a segmentarla.

Dico questo perchè ho provato a compilare un programma in C e visualizzare col debugger il corrispettivo codice assembly. Di fatto vedo il contenuto di tutti i registri della CPU e mi aspettavo che eseguendo il programma passo passo, il valore di CS, DS ed SS cambiasse invece rimane fisso.

Mi chiedo se questo comportemtno è dovuto al fatto che:

a) i segmenti sono di dimensione variabile e quindi il compilatore crea una zona di memoria che non verrà mai esaurita nel senso che, il mio programma non userà mai un altro segmento e quindi, non vedo cambiare i registri CS, DS,SS

b) il segmento è fisso ma il mio programma è di dimensioni talmente ridotte che sta comodamente in un segmento e per questo non vedo nessuna variazione

c) le variazioni dei registri DS, CS, SS li vedrei sse debugassi l'SO e non un mio programma
in modo x86 per cambiare segmento bisogna andare oltre i 64k
altrimenti e' sufficente l'offset..

La CPU in modo x86 vede la memoria in questo modo :

0000:0001 AB
0000:0002 1A
0000:0003 E3

dove il primo numero di 4 cifre esadecimale e' il registro di segmento CS (code segment)
il secondo numero di 4 cifre hexadecimal e' il registro di offset IP (instruction pointer)
e il terzo numero e' il dato in memoria a 8 bit.

Segment + Offset determinano l'indirizzo fisico delle 20 linee di memoria della CPU 8086
(con sovrapposizione delle aree di segmento x i noti probblemi... )

In pratica occorre cambiare segmento se si oltrepassano i 64k di memoria..
oppure se bisogna indirizzare delle aree fuori i 64k del codice..

In particolare i file eseguibili *.com del dos erano tutti intrasegmento, quindi non era
possibile utilizzare piu' di 64k
per eseguibili piu' grandi si utilizzavano gli *.exe..

bye :D

cdimauro
25-04-2009, 17:53
Non è esatto. Anche coi COM era possibile utilizzare più di 64KB.

Per il codice si utilizza la tecnica dell'overlay.

Per i dati... si allocavano richiamando le funzioni del DOS. ;)

misterx
25-04-2009, 18:34
in modo x86 per cambiare segmento bisogna andare oltre i 64k
altrimenti e' sufficente l'offset..

La CPU in modo x86 vede la memoria in questo modo :

0000:0001 AB
0000:0002 1A
0000:0003 E3

dove il primo numero di 4 cifre esadecimale e' il registro di segmento CS (code segment)
il secondo numero di 4 cifre hexadecimal e' il registro di offset IP (instruction pointer)
e il terzo numero e' il dato in memoria a 8 bit.

Segment + Offset determinano l'indirizzo fisico delle 20 linee di memoria della CPU 8086
(con sovrapposizione delle aree di segmento x i noti probblemi... )

In pratica occorre cambiare segmento se si oltrepassano i 64k di memoria..
oppure se bisogna indirizzare delle aree fuori i 64k del codice..

In particolare i file eseguibili *.com del dos erano tutti intrasegmento, quindi non era
possibile utilizzare piu' di 64k
per eseguibili piu' grandi si utilizzavano gli *.exe..

bye :D

quindi se scrivo un programma che sta nei 64K non vedrò mai variazioni di segmento ?

cdimauro
25-04-2009, 20:44
Come ho già scritto poco sopra, è possibile invece.

misterx
25-04-2009, 20:45
Come ho già scritto poco sopra, è possibile invece.

ho provato ad allocare quantità assurde e non vedere alcuna variazione :stordita:

StateCity
25-04-2009, 21:04
Non è esatto. Anche coi COM era possibile utilizzare più di 64KB.

Per il codice si utilizza la tecnica dell'overlay.

Per i dati... si allocavano richiamando le funzioni del DOS. ;)
invece e' esatto... :rolleyes:

http://en.wikipedia.org/wiki/COM_file

"The COM format is the original binary executable format used in CP/M and MS-DOS. It is very simple; it has no header, and contains no metadata, only code and data. Its simplicity exacts a price, however: the binary has a maximum size of 65,280 (0xFF00) bytes (a little bit less than 64 KiB) and stores all its code and data in one segment."

poi volendo avevi anche la libberta' di fare come ti pare.. :rolleyes:

"In the .COM system, larger programs (up to the available memory size) can be loaded and run, but the system loader assumes that all code and data is in the first segment, and it is up to the .COM program to provide any further organization."

StateCity
25-04-2009, 21:12
quindi se scrivo un programma che sta nei 64K non vedrò mai variazioni di segmento ?
se vuoi variare il segmento CS puoi farlo, basta fare un salto lontano...

tipo JMP 00AA:0011

(intersegmento diretto opcode "EA")

Ma c'e' il rischio di fare un salto nel buio..
e facilmente si va' a pescare un opcode che blocca la cpu.. :D

oppure si puo' saltare in un area sovrapposta..

JMP B004:000A = elettrico B004A
JMP B003:001A = elettrico B004A
JMP B002:002A = elettrico B004A

in modo 8086 compatibile sono tutti salti alla stessa locazione di memoria...

in questo caso e' facile cambiare CS e IP all' interno di un piccolo programma.

cdimauro
25-04-2009, 21:25
invece e' esatto... :rolleyes:

http://en.wikipedia.org/wiki/COM_file

"The COM format is the original binary executable format used in CP/M and MS-DOS. It is very simple; it has no header, and contains no metadata, only code and data. Its simplicity exacts a price, however: the binary has a maximum size of 65,280 (0xFF00) bytes (a little bit less than 64 KiB) and stores all its code and data in one segment."

poi volendo avevi anche la libberta' di fare come ti pare.. :rolleyes:

"In the .COM system, larger programs (up to the available memory size) can be loaded and run, but the system loader assumes that all code and data is in the first segment, and it is up to the .COM program to provide any further organization."

Esattamente come avevo detto io. :read:

Grazie per la conferma. :Prrr:

StateCity
25-04-2009, 21:28
Esattamente come avevo detto io. :read:

Grazie per la conferma. :Prrr:
anche se nn hai raggione,
se avessi una ragazza che mi sta' appresso come te' sarei il maschio il piu' felice del mondo.. :Prrr:


ciao caro :D

misterx
25-04-2009, 21:46
se vuoi variare il segmento CS puoi farlo, basta fare un salto lontano...

tipo JMP 00AA:0011

(intersegmento diretto opcode "EA")

Ma c'e' il rischio di fare un salto nel buio..
e facilmente si va' a pescare un opcode che blocca la cpu.. :D

oppure si puo' saltare in un area sovrapposta..

JMP B004:000A = elettrico B004A
JMP B003:001A = elettrico B004A
JMP B002:002A = elettrico B004A

in modo 8086 compatibile sono tutti salti alla stessa locazione di memoria...

in questo caso e' facile cambiare CS e IP all' interno di un piccolo programma.


da chi viene variato il registro DS ?

StateCity
25-04-2009, 22:13
http://www.itipedia.org/images/f/fa/8086.pdf
http://www.ece.unm.edu/faculty/jimp/310/slides/assem3.html
http://www.cad.polito.it/~sonza/05chj/dispense/ASSEM_01.pdf
http://www.ing.unife.it/elettr/CE/8086Asm02-03.pdf

tutti documenti molto utili.. :D

basta sgooglare "assembler 8086" non assembly :asd:

altrimenti nun se trova nulla.. :asd:

StateCity
25-04-2009, 22:33
una session di debug dos...


0D03:0100 B80B0A mov ax,0A0B
0D03:0103 8ED8 mov es,ax
0D03:0105 8EC0 mov ds,ax
0D03:0107 90 nop
0D03:0109 90 nop


carica in ES e DS il valore diretto di 0A0B

cdimauro
26-04-2009, 06:38
anche se nn hai raggione,
se avessi una ragazza che mi sta' appresso come te' sarei il maschio il piu' felice del mondo.. :Prrr:

ciao caro :D
Sarebbero tanti i maschietti, per cui non so quanto potresti essere felice visto che faresti parte di una fooooooooolta schiera. :asd:

Tornando a noi:
In particolare i file eseguibili *.com del dos erano tutti intrasegmento, quindi non era
possibile utilizzare piu' di 64k
per eseguibili piu' grandi si utilizzavano gli *.exe..

bye :D
Non è esatto. Anche coi COM era possibile utilizzare più di 64KB.

Per il codice si utilizza la tecnica dell'overlay.

Per i dati... si allocavano richiamando le funzioni del DOS. ;)
A meno che tu non voglia ridefinire il significato del verbo "usare", le cose stanno come ho detto io. :read: :Prrr:

misterx
26-04-2009, 09:06
una session di debug dos...


0D03:0100 B80B0A mov ax,0A0B
0D03:0103 8ED8 mov es,ax
0D03:0105 8EC0 mov ds,ax
0D03:0107 90 nop
0D03:0109 90 nop


carica in ES e DS il valore diretto di 0A0B


preso da qui (http://www.cpu-world.com/Arch/8088.html)

Data segment (DS) is a 16-bit register containing address of 64KB segment with program data. By default, the processor assumes that all data referenced by general registers (AX, BX, CX, DX) and index register (SI, DI) is located in the data segment. DS register can be changed directly using POP and LDS instructions.

E' il registro che contiene l'indirizzo dei vari segmenti di dimensioni di 64KB e tali segmenti contengono i dati usati e quindi caricati nei registri (AX, BX, CX, DX) ed i registri indice (SI, DI).

La parte in grassetto dice che DS può essere cambiato direttamente dal programmatore quindi usando opportune istruzioni: quindi far puntare i registri (AX, BX, CX, DX) e (SI, DI) è compito del programmatore assembly e non è un automatismo della cpu come contrariamente credevo. :stordita:

StateCity
26-04-2009, 15:00
Sarebbero tanti i maschietti, per cui non so quanto potresti essere felice visto che faresti parte di una fooooooooolta schiera. :asd:

Tornando a noi:


A meno che tu non voglia ridefinire il significato del verbo "usare", le cose stanno come ho detto io. :read: :Prrr:
Tu saresti capace di mettere eseguibili in memoria video.. :Prrr:

StateCity
26-04-2009, 15:32
Sarebbero tanti i maschietti, per cui non so quanto potresti essere felice visto che faresti parte di una fooooooooolta schiera. :asd:

Tornando a noi:


A meno che tu non voglia ridefinire il significato del verbo "usare", le cose stanno come ho detto io. :read: :Prrr:
Ma siccome i file *.com di tipo eseguibile sono stati implementati la prima volta nel CP/M
che nn poteva indirizzare piu' di 64k ecco che e' rimasto il limite del segmento... :O
il supero della capacita' e' stato dato solo dalle facilitazioni del dos..
come la memoria maggiore di un mega in modo 8086 del 386 :Prrr:

StateCity
26-04-2009, 15:58
preso da qui (http://www.cpu-world.com/Arch/8088.html)

Data segment (DS) is a 16-bit register containing address of 64KB segment with program data. By default, the processor assumes that all data referenced by general registers (AX, BX, CX, DX) and index register (SI, DI) is located in the data segment. DS register can be changed directly using POP and LDS instructions.

E' il registro che contiene l'indirizzo dei vari segmenti di dimensioni di 64KB e tali segmenti contengono i dati usati e quindi caricati nei registri (AX, BX, CX, DX) ed i registri indice (SI, DI).

La parte in grassetto dice che DS può essere cambiato direttamente dal programmatore quindi usando opportune istruzioni: quindi far puntare i registri (AX, BX, CX, DX) e (SI, DI) è compito del programmatore assembly e non è un automatismo della cpu come contrariamente credevo. :stordita:

non vedo perche' utilizzare pop e lds
quando si puo' fare direttamente con mov ds,ax..
forse si risparmia qualche ciclo di clock.. :stordita:

il segmento ds e' implicito se si scrive :

0000:0100 8B04 mov ax,[si]

la cpu prende implicitamente il segmento DS per formare l'indirizzo in memoria DS:SI

altrimenti si deve specificare direttamente..

0000:0102 368B04 mov ax,[ss:si]

(si nota che 36hex e' il prefisso di segmento.. )

e in debug verrebbe scritto solo cosi' :

0000:0102 36 ss:
0000:0103 8B04 mov ax,[si]

essedo il resto dell'opcode uguale al primo sopra.. :stordita:

in questo caso e' l'indirizzo e' formato da SS:SI

Questo si studia nei 7 modi di indirizzamento delle cpu 8086.. du :O :O

ma sono sicuro che cdimauro avra' qualcosa da ridire.. :asd:

misterx
26-04-2009, 16:28
non vedo perche' utilizzare pop e lds
quando si puo' fare direttamente con mov ds,ax..
forse si risparmia qualche ciclo di clock.. :stordita:

il segmento ds e' implicito se si scrive :

0000:0100 8B04 mov ax,[si]

la cpu prende implicitamente il segmento DS per formare l'indirizzo in memoria DS:SI

altrimenti si deve specificare direttamente..

0000:0102 368B04 mov ax,[ss:si]

(si nota che 36hex e' il prefisso di segmento.. )

e in debug verrebbe scritto solo cosi' :

0000:0102 36 ss:
0000:0103 8B04 mov ax,[si]

essedo il resto dell'opcode uguale al primo sopra.. :stordita:

in questo caso e' l'indirizzo e' formato da SS:SI

Questo si studia nei 7 modi di indirizzamento delle cpu 8086.. du :O :O

ma sono sicuro che cdimauro avra' qualcosa da ridire.. :asd:


però non hai risposto alla mia domanda e cioè se è il programmatore a variare l'indirizzo contenuto in DS.
Mi chiedo anche come fa la CPU a leggere all'indirizzo DS nel senso che, ho capito che tale indirizzo viene usato dai registri AX, etc.. ma come avviene l'incremento per puntare al prossimo dato per la prossima istruzione ?

StateCity
26-04-2009, 16:35
cmq. dipende anche dalla variabile puntatore...

MOV ax,[si] utilizza DS come segmento implicito (se non diversamente specificato nel prefisso)
MOV ax,[bp] utilizza SS come segmento implicito (se non diversamente specificato nel prefisso)

In ogni caso il programma *.com prevede che tutto sia dentro i 64k
quindi assume che CS=ES=SS=DS..
e allora non c'e' necessita' di specificare valori diversi per il segmento.

se si volesse scirvere/leggere in un area di memoria esterna ai 64k
si possono comunque cambiare i valori del registro DS

MOV AX, B000 (carica in AX il valore B000)
MOV DS,AX (carica in DS il valore di AX)
MOV AX,[SI] (carica in AX il valore della memoria B000:SI )

con LDS si dovrebbe prima scrivere il valore di DS in area memoria dati, e poi richiamare
la funzione LDS che assieme a DS carica pure l'operando destinazione.. :rolleyes:

IMHO.. :stordita:

StateCity
26-04-2009, 16:38
però non hai risposto alla mia domanda e cioè se è il programmatore a variare l'indirizzo contenuto in DS.
Mi chiedo anche come fa la CPU a leggere all'indirizzo DS nel senso che, ho capito che tale indirizzo viene usato dai registri AX, etc.. ma come avviene l'incremento per puntare al prossimo dato per la prossima istruzione ?
La CPU esegue le istruzioni indirizzate da CS:IP
e IP viene incrementato automaticamente alla frequenza di clock.. :stordita:

x Gli altri registri e' compito del sistema operativo dare i valori iniziali per il programma..
in modo che non vadano ad interferire con altri processi della cpu :stordita:

misterx
26-04-2009, 16:51
La CPU esegue le istruzioni indirizzate da CS:IP
e IP viene incrementato automaticamente alla frequenza di clock.. :stordita:

x Gli altri registri e' compito del sistema operativo dare i valori iniziali per il programma..
in modo che non vadano ad interferire con altri processi della cpu :stordita:

e in assenza di un SO, caso tipico dei programmi DOS, ci deve pensare il programma stesso ad indirizzare la CPU nel segmento appropriato per prelevare i dati(parametri) corretti ?

StateCity
26-04-2009, 17:00
partiamo dall' inizio... :D

* La cpu si "risveglia" sempre con dei valori predefiniti dei registri, imposti dalla fabbrica..
ed esegue subito la prima istruzione indirizzata da CS:IP....

* IP viene sempre incrementato alla frequenza di clock, per eseguire
le istruzzioni successive e nn si ferma mai ! :O (almeno fin quando c'e' la corrente o nn crasha.. :stordita: )

* le prime istruzioni che la CPU esegue sono solitamente routine di bios..
che una volta eseguite passano a caricare il boot sector dell' hard disk..

* il progtramma del boot sector cerca di mandare in esecuzione i files del
sistema operativo

* il sistema operativo prende il controllo della macchina...

* nel caso di esecuzioni di programmi utente e' compito del sistema operativo
impostare i registri che il programma trovera' pronti da utilizzare..

quindi e' il sistema operativo che imposta i valori di ES,DS,SS ecc. ecc.
che possono variare di volta in volta a secondo dell' area assegnata (dal SO)
ai programmi untente...

StateCity
26-04-2009, 17:01
e in assenza di un SO, caso tipico dei programmi DOS, ci deve pensare il programma stesso ad indirizzare la CPU nel segmento appropriato per prelevare i dati(parametri) corretti ?
il DOS significa appunto Disk Operating System. :stordita:

al lancio di un programma il DOS imposta automaticamente ES SS CS DS
in modo da assegnare un area di memoria libera al programma utente..

misterx
26-04-2009, 17:13
il DOS significa appunto Disk Operating System. :stordita:

al lancio di un programma il DOS imposta automaticamente ES SS CS DS
in modo da assegnare un area di memoria libera al programma utente..

scusa ma per DOS intenedvo la solita finestra(ehm...schermo) nero :D
Una domanda che ho trovato su un libro recita: è strettamente necessario un SO per far girare un programma ?
La risposta è no!
Da qui è scaturita la mia domanda.

Ad ogni modo ho capito che la CPU attraverso IP punta alla prossima istruzione nel segmento istruzioni partendo da CS; per indirizzare i dati ci deve pensare il programma stesso.

StateCity
26-04-2009, 17:30
scusa ma per DOS intenedvo la solita finestra(ehm...schermo) nero :D
Una domanda che ho trovato su un libro recita: è strettamente necessario un SO per far girare un programma ?
La risposta è no!
Da qui è scaturita la mia domanda.

Ad ogni modo ho capito che la CPU attraverso IP punta alla prossima istruzione nel segmento istruzioni partendo da CS; per indirizzare i dati ci deve pensare il programma stesso.
perfettamente.. :)

il bios, il boot sector, il so stesso sono programmi che funzionano senza SO
il SO e' un "manager" che facilita l'utilizzo della macchina e si occupa
di assegnare ai programmi delle aree libere di memoria,
di organizzare i dati sull' hard disk in files,
e altre utilita' di questo tipo...

in effetti un floppy disk formattato dos, ma vuoto, ha in realta' sempre un piccolo
programma dentro.. e' il programma di boot sector.. :fagiano:

bye :D

cdimauro
26-04-2009, 18:55
Tu saresti capace di mettere eseguibili in memoria video.. :Prrr:
Certo. Tutto fa brodo, quando si fa metal bashing. :cool:
Ma siccome i file *.com di tipo eseguibile sono stati implementati la prima volta nel CP/M
che nn poteva indirizzare piu' di 64k ecco che e' rimasto il limite del segmento... :O
Ma il DOS non è il CP/M. :fagiano:
il supero della capacita' e' stato dato solo dalle facilitazioni del dos..
Se rimaniamo vincolati ai soli 8086, sì. E però così non fai che darmi ragione ancora una volta. :cool:
come la memoria maggiore di un mega in modo 8086 del 386 :Prrr:
No, in questo caso il DOS non c'entra, se non per i primi 64KB - 16 byte posti a $10000, nei quali esso poteva piazzare alcune sue componenti e driver.

C'entrano però alcune succulente capacità del 386 che permettevano di andare ben oltre. :sbav:
non vedo perche' utilizzare pop e lds
quando si puo' fare direttamente con mov ds,ax..
forse si risparmia qualche ciclo di clock.. :stordita:

il segmento ds e' implicito se si scrive :

0000:0100 8B04 mov ax,[si]

la cpu prende implicitamente il segmento DS per formare l'indirizzo in memoria DS:SI

altrimenti si deve specificare direttamente..

0000:0102 368B04 mov ax,[ss:si]

(si nota che 36hex e' il prefisso di segmento.. )

e in debug verrebbe scritto solo cosi' :

0000:0102 36 ss:
0000:0103 8B04 mov ax,[si]

essedo il resto dell'opcode uguale al primo sopra.. :stordita:

in questo caso e' l'indirizzo e' formato da SS:SI

Questo si studia nei 7 modi di indirizzamento delle cpu 8086.. du :O :O

ma sono sicuro che cdimauro avra' qualcosa da ridire.. :asd:
No, proprio su questo non ho nulla di dire. Spiegazione da manuale. :fagiano:
La CPU esegue le istruzioni indirizzate da CS:IP
e IP viene incrementato automaticamente alla frequenza di clock.. :stordita:
Su questo invece sì, ma non ti dico il perché. :asd:

misterx
26-04-2009, 18:56
parlando di boot sector



START: START OF BOOT SECTOR PROGRAM

0000:7C3E FA CLI interrupts off
0000:7C3F 33C0 XOR AX,AX set AX to zero
0000:7C41 8ED0 MOV SS,AX SS is now zero
0000:7C43 BC007C MOV SP,7C00 SP is now 7c00
0000:7C46 16 PUSH SS also set ES
0000:7C47 07 POP ES to zero



fonte: http://www.ata-atapi.com/hiwdos.html#T10

la prima istruzione parte che dall'indirizzo 7C3E, la CPU vi trova FA; a questo punto IP si incrementa della dimensione dell'istruzione in quanto è ampia 1 byte ?
Quindi IP conosce la dimensione dell'istruzione.
L'esempio mostra poi che la prossima istruzione si trova al byte successivo e che è formata questa volta da 2 byte, quindi IP avanza di 2 byte in quanto sa che l'istruzione che è stata eseguita era di due byte.
Arrivati alle MOV queste sono ampie due byte, le PUSH 1 byte, idem per le POP che sono di 1 byte: come fa IP sostanzialmente a sapere di quanto deve avanzare ?
Chi glielo dice ?

Purtroppo le risposte non si trovano nei libri :stordita:

StateCity
26-04-2009, 19:14
http://212.189.172.195/corso/labsitel/docs/8086/80861.pdf
http://home.comcast.net/~fbui/intel.html

in pratica l' IP si incrementa sempre di 1 ...
(salvo se non viene modificato da istruzioni di salto o altri casi)
sara' poi la CPU a decidere cosa fare del dato indirizzato da CS:IP.. :rolleyes:
potrebbe essere un OpCode di un istruzione, oppure un dato numerico da elaborare..

StateCity
26-04-2009, 19:20
altre info sull' argomento.. Istruction Pointer o Program Counter.. :fagiano:

http://it.wikipedia.org/wiki/Program_counter
http://it.wikipedia.org/wiki/Ciclo_di_fetch-execute
http://en.wikipedia.org/wiki/Program_counter
http://en.wikipedia.org/wiki/Instruction_cycle

StateCity
26-04-2009, 19:26
0000:7C3E FA CLI
0000:7C3F 33C0 XOR AX,AX
0000:7C41 8ED0 MOV SS,AX
0000:7C43 BC007C MOV SP,7C00
0000:7C46 16 PUSH SS
0000:7C47 07 POP ES

Qui il disassemblatore, (tipo debug o altri) fa' vedere solo il primo offset della memoria (in rosa)
relativo all' istruzione da eseguire...

ma in pratica sarebbe :
0000:7C3E FA
0000:7C3F 33
0000:7C40 C0
0000:7C41 8E
0000:7C42 D0

ecc ecc

misterx
26-04-2009, 19:42
0000:7C3E FA CLI
0000:7C3F 33C0 XOR AX,AX
0000:7C41 8ED0 MOV SS,AX
0000:7C43 BC007C MOV SP,7C00
0000:7C46 16 PUSH SS
0000:7C47 07 POP ES

Qui il disassemblatore, (tipo debug o altri) fa' vedere solo il primo offset della memoria (in rosa)
relativo all' istruzione da eseguire...

ma in pratica sarebbe :
0000:7C3E FA
0000:7C3F 33
0000:7C40 C0
0000:7C41 8E
0000:7C42 D0

ecc ecc


quindi è solo un problema di visualizzazione!
Allora si che si spiega l'incremento di 1 byte alla volta :)

StateCity
26-04-2009, 19:56
Certo. Tutto fa brodo, quando si fa metal bashing. :cool:

Ma il DOS non è il CP/M. :fagiano:

Se rimaniamo vincolati ai soli 8086, sì. E però così non fai che darmi ragione ancora una volta. :cool:

No, in questo caso il DOS non c'entra, se non per i primi 64KB - 16 byte posti a $10000, nei quali esso poteva piazzare alcune sue componenti e driver.

C'entrano però alcune succulente capacità del 386 che permettevano di andare ben oltre. :sbav:
avessi una ragazza che mi sta' cosi attaccata... :O :cry:

No, proprio su questo non ho nulla di dire. Spiegazione da manuale. :fagiano:
Detto da te' e' sicuramente un grosso complimento ! :sofico:
Su questo invece sì, ma non ti dico il perché. :asd:
restero' nella mia ignoranza.. :cry:

StateCity
26-04-2009, 20:05
quindi è solo un problema di visualizzazione!
Allora si che si spiega l'incremento di 1 byte alla volta :)

Perfettamente.. :D

il debugger tenta di interpretare i codici esadecimali e ricavare le istruzioni...
se vede la sequenza BC 00 7C la interpreta come MOV SP,7C00
anche se quei valori potrebbero essere i colori di una foto..
oppure una sequenza di caratteri ascii..

la memoria e' sempre organizzata in questo modo..

Indirizzo ... dato (byte)
00001 ....... xx
00002 ....... xx
00003 ....... xx

ecc. ecc.

bye :D

cdimauro
26-04-2009, 21:16
avessi una ragazza che mi sta' cosi attaccata... :O :cry:
Tranquillo: per quello bastano anche altre doti. :oink:
Detto da te' e' sicuramente un grosso complimento ! :sofico:
Beh, è la verità. :)
restero' nella mia ignoranza.. :cry:
Vabbé, dai, per così poco. :D Il punto errato è questo:

"IP viene incrementato automaticamente alla frequenza di clock"

IP viene incrementato quando la sezione di fetch & decode ha terminato il suo lavoro.

Quindi quest'operazione è legata strettamente all'implementazione, e alla particolare istruzioni prelevata. Può avvenire una sola volta in un ciclo di clock, più volte (visto che le CPU moderne possono prelevare, decodificare ed eseguire più istruzioni per ciclo di clock) per ciclo di clock, o anche nessuna volta.

misterx
27-04-2009, 06:02
Perfettamente.. :D

il debugger tenta di interpretare i codici esadecimali e ricavare le istruzioni...
se vede la sequenza BC 00 7C la interpreta come MOV SP,7C00
anche se quei valori potrebbero essere i colori di una foto..
oppure una sequenza di caratteri ascii..

la memoria e' sempre organizzata in questo modo..

Indirizzo ... dato (byte)
00001 ....... xx
00002 ....... xx
00003 ....... xx

ecc. ecc.

bye :D

quel tenta è preoccupante :stordita:

cdimauro
27-04-2009, 07:30
No, è normale, perché quello fornito col DOS è molto vecchio e riconosce soltanto una piccola porzione degli opcode delle CPU moderne. E' fermo agli 8086. :D