Avatar billede mobsterc Nybegynder
27. oktober 2005 - 16:58 Der er 19 kommentarer

Arrays adresse til 2 unsigned int

Hej

Jeg har et problem jeg har jongleret lidt med, men har ikke kunne løse det.

Jeg sidder og laver et testprogram i Paradigm C++ til en AMD186ER. Det er et lille testprogram der skal teste 186'eres DMA.

Problemet er at jeg skal sætte nogle source og destination registre, og her skal jeg bruge adresserne på det array der skal overføres fra, til det array jeg vil overfører til. Der er 20 adressebits, det vil sige at jeg skal bruge 2 16-bits variabler til at holde adressen.

Hvis jeg har følgende array
unsigned int testarr[10];
og de 2 variabler
unsigned int highaddr, lowaddr;

Hvordan får jeg så de 4 øverste adresse-bits på testarr[0] til at ligge i highaddr, og de 16 laveste adresse-bits til at ligge i lowaddr?

Har prøvet med &testarr[0], men får fejl i alt det jeg har prøvet.

Håber nogen kan hjælpe.

/Mob
Avatar billede arne_v Ekspert
27. oktober 2005 - 17:02 #1
unsigned int testarr[10];
unsigned int highaddr, lowaddr;
highadr = ((&testarr[0]) >> 16) & 0x000F;
lowadr = (&testarr[0]) & 0xFFFF;

var værd at prøve
Avatar billede mobsterc Nybegynder
27. oktober 2005 - 17:12 #2
Jeg får 2 "Illegal use of pointer" fejl ved

highadr = ((&testarr[0]) >> 16) & 0x000F;
lowadr = (&testarr[0]) & 0xFFFF;
Avatar billede mollevp Nybegynder
27. oktober 2005 - 18:04 #3
Måske:
highadr = ((testarr[0]) >> 12) & 0x000F;
lowadr = (testarr[0]) & 0xFFFF;

Men hvis en unsigned int er 16 bit og du skal bruge de første 20 bit fra testarr[]
skulle det så ikke være:

highadr = ((testarr[1]) & 0x000F;
lowadr = (testarr[0]) & 0xFFFF;

Eller er det mig der er forvirret?
Avatar billede mobsterc Nybegynder
27. oktober 2005 - 18:32 #4
Det er ikke indholdet af arrayet jeg skal bruge, det er den 20-bits adresse hvor testarr[0] ligger som jeg skal bruge!
Avatar billede mollevp Nybegynder
27. oktober 2005 - 18:51 #5
Så tror jeg du skal cast adressen først ala:

highadr = (((unsigned int)testarr) >> 12) & 0x000F;
lowadr = ((unsigned int)testarr) & 0xFFFF;
Avatar billede mollevp Nybegynder
27. oktober 2005 - 18:58 #6
ummh nej det går jo da vist ikke godt.. hmm
Avatar billede mollevp Nybegynder
27. oktober 2005 - 19:08 #7
Har du ikke en 20bit type du kan caste til? Jeg tror ikke nemlig ikke du kan caste en 20 bit adresse til en 16bit type uden problemer..
Avatar billede mobsterc Nybegynder
27. oktober 2005 - 19:50 #8
jeg har en unsigned long int på 32 bit.
Avatar billede bertelbrander Praktikant
27. oktober 2005 - 19:51 #9
Dette oversætter:
  unsigned int testarr[10];
  unsigned long T = (unsigned long )&testarr;
  unsigned int highaddr, lowaddr;
  lowaddr = (unsigned int )T;
  highaddr = (unsigned int )(T >> 16);
  printf("%p %X %X", &testarr[0], highaddr, lowaddr);

Men jeg tvivler på at det virker.
Din compiler har sansynligvis en header fil med macro'er til at finde offset og segment fra en pointer.
Avatar billede mollevp Nybegynder
27. oktober 2005 - 19:56 #10
Hvorfor ikke Bertel?
Avatar billede bertelbrander Praktikant
27. oktober 2005 - 20:01 #11
Fordi en adresse på en 186'er er delt i et segment og et offset.
Den fysiske adresse findes med: (segment << 4) + offset.
Derfor er der kun 20 bit ud af en (tilsynladende) 32 bit værdi.

Gamle Borland compilere havde: MK_FP FP_SEG og FP_OFF til at oversætte mellem offset/segment og adresse og tilbage.
Avatar billede mollevp Nybegynder
27. oktober 2005 - 20:08 #12
ok, det kunne nok godt skabe problemer..
Avatar billede mobsterc Nybegynder
27. oktober 2005 - 20:31 #13
Jeps, det skal bruges til at finde ud af hvilken 20 bit adresse arrayet ligger på så den kan initialisere DMA overførsel.

Ovenstående virker ikke, det giver kun 0x410 og burde give noget over 0xE0000. Vil det sige at jeg med C++ ikke har nogen mulighed for at finde ud af hvilken adresse en variabel ligger på, for den skal som sagt bruge de 20 bits i source og destination-registre til DMA-overførslen.
Avatar billede bertelbrander Praktikant
27. oktober 2005 - 20:33 #14
Du skal sansynligvis bruge en funktion/macro fra en af kompilerens ikke standard header filer, Borland har dem til at ligge i dos.h
Avatar billede mobsterc Nybegynder
27. oktober 2005 - 20:38 #15
Oki, jeg bruger også dos.h, har du et tip til hvad jeg skal lede efter?
Avatar billede bertelbrander Praktikant
27. oktober 2005 - 20:43 #16
FP_SEG -> segment fra far pointer
FP_OFF -> offset af far pointer
Avatar billede mobsterc Nybegynder
27. oktober 2005 - 20:55 #17
Den har følgende i dos.h, hvordan bruges det til at få adressen?

#define MK_FP(seg,ofs) ((void __seg *)(seg) + (void __near *)(ofs))
#define FP_SEG(fp)    ((unsigned)(void __seg *)(void __far *)(fp))
#define FP_OFF(fp)    ((unsigned)(fp))
Avatar billede bertelbrander Praktikant
27. oktober 2005 - 20:59 #18
unsigned int testarr[10];
unsigned int highadr = FP_SEG(testarr);
unsigned int lowadr = FP_OFF(testarr);

Eller:
unsigned int highadr = FP_SEG(&testarr[0]);
unsigned int lowadr = FP_OFF(&testarr[0]);
Avatar billede mobsterc Nybegynder
03. november 2005 - 23:48 #19
super, var lige det jeg skulle bruge!
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester