Newsgroup: it.comp.lang.c
Titolo: Offset e puntatori

Ciao ragazzi sto scimunendo da na settimana e forse oggi ho capito dove 
sbaglio ma non so ancora come poter correggere le righe di codice "infette".
Ho creato un puntatore per il quale ho allocato 192000 byte. Ho esigenza di 
accedere ad ogni cella ampia 1 byte.
Ho scoperto perň che purtroppo l'offset che inserisco tra le parentesi 
[offset] puň essere massimo 65535, ovvero il valore massimo che si ottiene 
con 2 byte.
Facendo qualche ricerca ho scoperto che bisognerebbe utilizzare uno 
stratagemma che si basa sul suddividere l'indirizzo in 2 parti separate dal 
":" ovvero:
segmento:offset
Il quale se ho capito bene poi in automatico mi calcola l'indirizzo 
effettivo in questo modo:
indirizzo = (segmento * 16) + offset
non ho capito bene perň come procedere. Vi faccio un esempio:
typedef unsigned char    byte;
byte *data;
if ((data=(byte *)malloc(200*960))==NULL) {
  printf("\nERRORE: non č possibile allocare questo spazio di memoria!");
  exit(1);
}
for (y=0;y<200;y++) {
    for (x=0;x<960;x++) {
        data[x+(y*960)] = 0;
    }
}
Come posso convertire questo ciclo for utilizzando la tecnica del 
segmento:offset ?
Ho letto poi che segmento ed offset sono indicati solitamente in notazione 
esadecimale, ma posso utiizzare anche la notazione decimale?
?
Ringrazio tutti coloro mi risponderanno. :) 

Sto utilizzando un compilatore abbastanza vecchiotto il Borland c++ 3.1
perchè mi serve lavorare sotto DOS in modalità 13h.
Sto già utilizzando il modello large, che più o meno è simile ad
huge solo che huge permette in più di utilizzare fino a 1mb di dati
statici e globali.
In ogni caso ho provato ad utilizzare huge ma il problema rimane.
Io credo che il mio problema non sia dovuto all'allocazione della
memoria, poichè large permette di allocare fino a 640kb per i dati
heap, e con queste istruzioni non dovrei incontrare problemi:
  if ((data=(byte *)malloc(200*960))==NULL) {
      printf("\nERRORE: non è possibile allocare questo spazio di
memoria!");
      exit(1);
  }
più che altro il mio problema è quello di accedere ad ogni singolo
byte allocato, e a quanto pare l'istruzione:
  data[offset] = 0;
va bene solo fino a quando offset è minore di 65535.
Utilizzando il metodo di segmento:offset invece pare si possa ottenere
un indirizzo lineare a 20bit che dovrebbe risolvere tutti i miei
problemi! Non sò però come utilizzarlo, e sono quindi alla ricerca di
esempi, sarebbe il massimo se mi venisse tradotto questo spezzone di
codice:
for (y=0;y<200;y++) {
    for (x=0;x<960;x++) {
        data[x+(y*960)] = 0;
    }
}
qui ad esempio l'offset arriva fino ad un numero massimo pari a 191999
di molto superiore alla soglia limite di 65535.
Ciao
Carmine

 superiore a 65535 bytes?
Sotto tuo consiglio ho provato ad utilizzare il modello huge e a dichiarare 
i puntatori di tipo huge e FUNZIONA!!!
Funziona anche utilizzando il modello large e dichiarando puntatori di tipo 
huge!
Volevo farti una domanda: ho letto che il modello large di default imposta i 
puntatori di tipo far sai per caso se anche il modello huge imposta di 
default i puntatori huge? Ti faccio questa domanda poichè utilizzando il 
modello di memoria huge e non dichiarando i puntatori di tipo huge quando 
eseguo il programma non ottengo i risultati attesi!
Inoltre voglio chiederti se utilizzando i puntatori di tipo huge posso 
utilizzare normalmente la funzione malloc o devo utilizzare qualche altra 
funzione?
Grazie sei stato gentilissimo!
Ciao
Carmine 


Nel mio precedente post ti chiedevo se hai la possibilita` di usare il 
modello HUGE, perche` in certe situazioni puoi fare tutto 
automaticamente se dichiari una struttura di 16 bytes (16 e` un buon 
valore perche` il compilatore usa shift ed AND per divisione e modulo 
rispettivamente). Per esempio
struct struc_s {
    char data[16];
};
char *bytePtr;
struct struc_s *pointer = malloc(200*960);
bytePtr = &(pointer[offset/sizeof(struct struc_s)].data[offset %
		sizeof(struct struc_s)]);
Se poi (200*960) significa che hai un array di 200 strutture di 960 byte 
puoi usare questi valori.  Attento che la dimensione della struct deve 
essere un multiplo di 16 altimenti il compilatore la allinea per avere 
un valore 0 nella parte offset.
In alternativa nel file dos.h del mio vecchio compilatore Microsoft 6.1 
ho trovato queste macro:
#define FP_SEG(fp) (*((unsigned _far *)&(fp)+1))
#define FP_OFF(fp) (*((unsigned _far *)&(fp)))
char *pointer, *data;
pointer = malloc(200*960);
FP_SEG(data) = FP_SEG(pointer) + offset / 16;
FP_OFF(data) = FP_SEG(pointer) + offset % 16;
Non ho` modo di verificare se i due esempi siano OK ma li ho tirati 
fuori dai miei ricordi di quando usavo programmare per 80186 (e sono 
passati troppi anni) :-(   Verificali prima.


 funzione?
Anche qui non so risponderti.  Nel compilatore MS non esistono puntatori 
dichiarati huge ma solo far.
I puntatori far se usi il modello large si incrementano solo per la 
parte offset, se usi il modello huge si incrementano sia per la parte 
segment che per la parte offset.


 dichiarati huge ma solo far.
Che io mi ricordi, neanche con il compilatore Borland.
L'unica differenza di cui mi ricordi è tra near e far.
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it