Autor Thema: Hilfe bei PureC printf und Adressberechnung  (Gelesen 23877 mal)

0 Mitglieder und 2 Gäste betrachten dieses Thema.

guest522

  • Gast
Hilfe bei PureC printf und Adressberechnung
« am: Do 05.04.2012, 10:27:02 »
Hi,

ich steh auf dem Schlauch.....
Welche Adresse berechnet sich aus dem Ausdruck
(UBYTE *)(0xfedc8000L)  +  (int)(0x03c8-0x8000)
Wie stelle ich das per printf in hex dar? Ich bekomme immer nur 4-stellige Hex Ausgaben per %x
Was soll die -0x8000 bewirken?

Danke

Offline m0n0

  • Benutzer
  • Beiträge: 984
Re: Hilfe bei PureC printf und Adressberechnung
« Antwort #1 am: Fr 06.04.2012, 01:35:41 »
Hast Du beim Printf schon mal %p versucht? Ich meine das ist dafür da um Werte von Pointern auszugeben, sollte also genau das richtige sein....

guest522

  • Gast
Re: Hilfe bei PureC printf und Adressberechnung
« Antwort #2 am: Fr 06.04.2012, 11:47:47 »
Das funzt, danke! Ergebnis: fedc03c8
 d.h. die Addition findet nur im int Teil statt (?) und es ensteht kein "Übertrag" ins nächste Byte. Ich hätte fedd03c8 erwartet.
Wer kann mir das erklären?

Offline simonsunnyboy

  • Moderator
  • *****
  • Beiträge: 1.807
  • Rock'n'Roll is the thing - Jerry Lee is the king!
Re: Hilfe bei PureC printf und Adressberechnung
« Antwort #3 am: Fr 06.04.2012, 11:59:43 »
Was für eine Datenbreite benutzt int in deinem Compiler?
Wenn der nur 16Bit benutzt, dann geht natürlich etwas verloren.

Da Adressen (Pointer) am ST immer vom Typ unsigned long sind (4 Bytes)

Mein Ratschlag: Den Datentyp int grundsätzlich nicht benutzen und stattdessen immer die Typen verwenden, die eine wohldefinierte Länge an Bytes benutzen. Entweder selbst definierte, oder die Typen aus der GODLIB der Reservor Gods oder standardkonform stdint.h, welches Pure C aber leider per Default nicht bietet.

*NACHTRAG:* DIe Godlib inklusive ihrer Header habe ich in einem anderen Thread mal hochgeladen.
« Letzte Änderung: Fr 06.04.2012, 12:10:24 von simonsunnyboy »
Paradize - ST Offline Tournament
Stay cool, stay Atari!
1x2600jr, 1x1040STFm, 1x1040STE 4MB+TOS2.06+SatanDisk, 1xF030 14MB+FPU+NetUS-Bee

guest522

  • Gast
Re: Hilfe bei PureC printf und Adressberechnung
« Antwort #4 am: Fr 06.04.2012, 13:01:11 »
Es handelt sich um PureC.
Die Ursache ist aber wohl eher die Art wie C die Addition behandelt.

(UBYTE *)(0xfedc8000L) + (int)    (0x03c8-0x8000)  ==> fedc03c8
also
   FEDC 8000
 +      83C8
 -----------
   FEDC 03C8 Übertrag geht verloren


(UBYTE *)(0xfedc8000L) +  (long)(0x03c8-0x8000)  ==> fedd03c8

   FEDC 8000
 + 0000 83C8
 -----------
   FEDD 03C8 Übertrag findet statt

(ULONG *)(0xfedc8000L) +  (long)(0x03c8-0x8000)  ==> fede8f20
das versteh ich überhaupt nicht mehr:

   FEDC 8000
 + 0000 83C8
 -----------
   FEDE 8F20

das kann nur sein, wenn vor der Addition der 2. Operand um 2 bit nach links geschoben wird:

1111 1110 1101 1100 1000 0000 0000 0000
                 10 0000 1111 0010 00
---------------------------------------
1111 1110 1101 1110 1000 1111 0010 0000


Wer kann mir das erklären?

Offline simonsunnyboy

  • Moderator
  • *****
  • Beiträge: 1.807
  • Rock'n'Roll is the thing - Jerry Lee is the king!
Re: Hilfe bei PureC printf und Adressberechnung
« Antwort #5 am: Fr 06.04.2012, 13:03:45 »
Nein, das ist nicht Pure C, sondern der von Pure C generierte Assembler Code, der vermutliuch nur add.w erzeugt, obwohl du add.l für den Übertrag in die oberen Bytes bräuchtest.

Das liegt alles an den verwendeten Datentypen. Diese Auswahl beinflusst direkt den nötigen Maschinencode, und der kann problemlos Überträge weglassen.
Paradize - ST Offline Tournament
Stay cool, stay Atari!
1x2600jr, 1x1040STFm, 1x1040STE 4MB+TOS2.06+SatanDisk, 1xF030 14MB+FPU+NetUS-Bee

guest522

  • Gast
Re: Hilfe bei PureC printf und Adressberechnung
« Antwort #6 am: Fr 06.04.2012, 13:59:45 »
Nein, das ist nicht Pure C, sondern der von Pure C generierte Assembler Code, der vermutliuch nur add.w erzeugt, obwohl du add.l für den Übertrag in die oberen Bytes bräuchtest.
Die Aussage versteh ich nicht. Mir ist schon klar, dass ein C-Compiler binär Code (nicht Assembler!) erzeugt.
Mir ist auch klar, dass hier unterschiedliche Instruktionen zum Einsatz kommen. Was hier richtig oder falsch ist bzw. was ich bräuchte ist nicht die Frage.
Das liegt alles an den verwendeten Datentypen. Diese Auswahl beinflusst direkt den nötigen Maschinencode, und der kann problemlos Überträge weglassen.
siehe oben....ist mir alles bewusst. ich hätte es nur gern etwas präziser gewußt.  ;) D.h. welchen Regeln folgt eine Pointer Addition abhängig von der verwendeten Syntax.

Offline simonsunnyboy

  • Moderator
  • *****
  • Beiträge: 1.807
  • Rock'n'Roll is the thing - Jerry Lee is the king!
Re: Hilfe bei PureC printf und Adressberechnung
« Antwort #7 am: Fr 06.04.2012, 14:26:32 »
Pointerarithmetik folgt ganz regulär den Regeln der verwendeten Registern und wie auf sie zugegriffen wird. Sie unterscheidet sich absolut nicht vom normalen Rechnen.

Wenn du nur auf die unteren Bytes zugreifst, gibt es keinen Übertrag in die beiden oberen, ganz einfach.

C ist eigentlich nur ein besserer Makroassembler. EIn grundlegendes Verständnis für die Maschinenebene ist leider weiterhin zwingend nötig, um solche "Fallen" zu verstehen. Deswegen: Pointer für M68k = 32Bit = unsigned long = uint32_t = U32

Und mit Pointern nicht rechnen, wenn es nicht zwingend notwendig ist.

Was genau willst Du eigentlich technisch mit Deinem Konstrukt da machen?
Paradize - ST Offline Tournament
Stay cool, stay Atari!
1x2600jr, 1x1040STFm, 1x1040STE 4MB+TOS2.06+SatanDisk, 1xF030 14MB+FPU+NetUS-Bee

guest522

  • Gast
Re: Hilfe bei PureC printf und Adressberechnung
« Antwort #8 am: Fr 06.04.2012, 14:54:45 »
Pointerarithmetik folgt ganz regulär den Regeln der verwendeten Registern und wie auf sie zugegriffen wird. Sie unterscheidet sich absolut nicht vom normalen Rechnen.

Wenn du nur auf die unteren Bytes zugreifst, gibt es keinen Übertrag in die beiden oberen, ganz einfach.

C ist eigentlich nur ein besserer Makroassembler. EIn grundlegendes Verständnis für die Maschinenebene ist leider weiterhin zwingend nötig, um solche "Fallen" zu verstehen. Deswegen: Pointer für M68k = 32Bit = unsigned long = uint32_t = U32

Und mit Pointern nicht rechnen, wenn es nicht zwingend notwendig ist.

Was genau willst Du eigentlich technisch mit Deinem Konstrukt da machen?

Sei mir nicht böse, aber Deine Antwort ist mir zu unpräzise.  ;D
Das ist als wenn ich frage "Warum ist -2 +  2 = 0" und Du antwortest "Das folgt den Regeln der Mathematik".

Kannst Du an anhand der konkreten Instruktionen (vor allem das 3. Bsp.) erklären warum die Arithmetik genau das macht was sie macht? Diese Erklärung suche ich, damit ich das besser verstehe.

Was ich damit mache? Ich stricke wieder mal an der Nova rum.   

Gruß
Wolfgang

Offline simonsunnyboy

  • Moderator
  • *****
  • Beiträge: 1.807
  • Rock'n'Roll is the thing - Jerry Lee is the king!
Re: Hilfe bei PureC printf und Adressberechnung
« Antwort #9 am: Fr 06.04.2012, 18:52:08 »
Ich behaupte, wenn Du einfach sagst was Du genau ansprechen willst, dann gibt es bestimmt eine elegantere Lösung, die auch eindeutig zu verstehen ist.
Paradize - ST Offline Tournament
Stay cool, stay Atari!
1x2600jr, 1x1040STFm, 1x1040STE 4MB+TOS2.06+SatanDisk, 1xF030 14MB+FPU+NetUS-Bee

guest522

  • Gast
Re: Hilfe bei PureC printf und Adressberechnung
« Antwort #10 am: Fr 06.04.2012, 18:57:34 »
Ich behaupte, wenn Du einfach sagst was Du genau ansprechen willst, dann gibt es bestimmt eine elegantere Lösung, die auch eindeutig zu verstehen ist.


Ich dachte das wäre klar. ???
Das Verhalten der Ergebnise der 3 Anweisungen (vor allem die dritte) im ersten Posting erklären.
Und nochmal....es geht mir nicht um eine "elegantere Lösung", sondern darum es zu verstehen. ;)

Offline m0n0

  • Benutzer
  • Beiträge: 984
Re: Hilfe bei PureC printf und Adressberechnung
« Antwort #11 am: Sa 07.04.2012, 18:06:26 »
Hallo,

ich kenne das Problem mit PureC.... ich mache dann immer mehrere explizite casts bei der Rechenoperation:

((long)(long) bla + (long) bla2))

dann geht's ;)

guest522

  • Gast
Re: Hilfe bei PureC printf und Adressberechnung
« Antwort #12 am: So 08.04.2012, 12:48:51 »
Hallo,

ich kenne das Problem mit PureC.... ich mache dann immer mehrere explizite casts bei der Rechenoperation:

((long)(long) bla + (long) bla2))

dann geht's ;)

Ja so sichere ich mich auch immer ab, trotzdem würd ich gern wissen wie es zum shift im Beispiel oben kommt. Das lässt mir keine Ruhe. ;)

Offline nichtsnutz

  • Benutzer
  • Beiträge: 52
Re: Hilfe bei PureC printf und Adressberechnung
« Antwort #13 am: So 08.04.2012, 13:05:34 »
Hallo Idek,

Zitat
(ULONG *)(0xfedc8000L) +  (long)(0x03c8-0x8000)  ==> fede8f20
das versteh ich überhaupt nicht mehr:

   FEDC 8000
 + 0000 83C8
 -----------
   FEDE 8F20

das kann nur sein, wenn vor der Addition der 2. Operand um ein Byte nach links geschoben wird:


Nicht um ein Byte sondern um 2 Bits.
Du addierst zu einem (ULONG *) also einen Zeiger auf Zahlen die 4 Bytes belegen eine Konstante,nämlich das (long)(0x03c8-0x8000)  = 0x000083C8.Zeiger Arithmetik funktionirt so,dass die Konstante mit sizeof(ULONG)=4 multipliziert wird bevor sie zum Zeiger addiert wird.

Ich hoffe das ist verständlich !

Viele Gruesse,
Vassilis

P.S:Wenn ich das richtig verstehe besitzt du die Rechte und den kompletten Quellcode  der NOVA Treiber !? und/oder NVDI !?

Viele Grüsse,
Vassilis


guest522

  • Gast
Re: Hilfe bei PureC printf und Adressberechnung
« Antwort #14 am: So 08.04.2012, 13:35:46 »
Hi,

danke für die Erklärung!  :D
Natürlich 2 bit...ich seh den Wald vor Bäumen wohl nicht mehr...sorry!

Die Rechte habe ich nicht, den Quellcode darf ich aber verwenden um Änderungen durchzuführen. Das habe ich damals versucht um die Nova mit der CT60 kompatibel zu machen. Leider steht dem die CT60 Hardware im Wege.
Von NVDI habe ich nichts.


Noch ne Frage: Du schreibst
Zitat
Du addierst zu einem (ULONG *) also einen Zeiger auf Zahlen die 4 Bytes belegen eine Konstante,nämlich das (long)(0x03c8-0x8000)  = 0x000083C8.Zeiger Arithmetik funktionirt so,dass die Konstante mit sizeof(ULONG)=4 multipliziert wird bevor sie zum Zeiger addiert wird.
Warum passiert das bzw., wenn ich auf einen Zeiger auf 2 Byte addiere, wird dann mit 2 multipliziert? Also
(UWORD *)(0xfedc8000L) +  (long)(0x03c8-0x8000)  ==> fedd8790
 

Offline nichtsnutz

  • Benutzer
  • Beiträge: 52
Re: Hilfe bei PureC printf und Adressberechnung
« Antwort #15 am: So 08.04.2012, 13:54:13 »
Hallo Idek,

Zitat
danke für die Erklärung! 
Natürlich 2 bit...ich seh den Wald vor Bäumen wohl nicht mehr...sorry!

kein Problem,mir geht es oft auch so !

Zitat
Die Rechte habe ich nicht, den Quellcode darf ich aber verwenden um Änderungen durchzuführen. Das habe ich damals versucht um die Nova mit der CT60 kompatibel zu machen. Leider steht dem die CT60 Hardware im Wege.
Von NVDI habe ich nichts.
Ok,vielen Dank für die Information und viel Erfolg weiterhin,ich verfolge die NOVA Diskussion passiv,da ich andere Baustellen noch offen habe.

Es ist zwar hier offtopic,aber wie funktionieren diese Treiber grob beschrieben ?
Das GEM ist ja etwas modular aufgebaut soweit ich gelesen habe,also GEM = VDI + (GDOS?) + AES und der low level des VDI sind die LINEA $A000 Funktionen.
Reicht es die LINEA Funktionen umzuschreiben oder müssen grosse Teile des VDI/AES neugeschrieben werden ?

Viele Grüsse,
Vassilis

guest522

  • Gast
Re: Hilfe bei PureC printf und Adressberechnung
« Antwort #16 am: So 08.04.2012, 13:59:52 »
Es wird ein Handler installiert, der die VDI calls abfängt und entsprechend in eigene Assembler Routinen umleitet. Das GDOS bleibt unberührt, sodass man ein anderes GDOS (z.B. NVDI) einbinden kann.


Offline nichtsnutz

  • Benutzer
  • Beiträge: 52
Re: Hilfe bei PureC printf und Adressberechnung
« Antwort #17 am: So 08.04.2012, 14:22:23 »
Hallo Idek,

Oha,es wird also das ganze VDI neugeschrieben,gut, das ist also etwas aufwendiger !

Zitat
Warum passiert das bzw., wenn ich auf einen Zeiger auf 2 Byte addiere, wird dann mit 2 multipliziert?
Ja,das ist so.Es liegt an der Art wie C mit Zeigern rechnet.Wenn man zu einem Zeiger +1 addiert,ist es sinnvoll den Zeiger um ein Element auf das er zeigt zu erhöhen und nicht um ein Byte.Man würde ja sonst "irgendwo" im Speicher landen!
Es liegt halt in der Behandlung von Zeigern in der Sprache C die mit Arrays sehr verwand sind.

Viele Grüsse,
Vassilis