Autor Thema: Rückgabe von 128bit Datentypen  (Gelesen 9125 mal)

Sannaj

  • Beiträge: 103
    • Profil anzeigen
Gespeichert
« am: 30. October 2011, 17:39 »
Da ich ja bekanntlich kein OS sonder einen Compiler plane hab ich mir schon mal über alle Möglichen Dingen Gedanken gemacht. Ein Aspect sind ist die Rückgabe von 128 bit Daten (die mit int128 und Gleitkommazahlen vierfacher Genauigkeit unterstützt werden sollen.)

Bei der Rückgabe solcher Zahlen von Funktionen gibt es folgende Ansprüche
- ecx ist für die Fehlerrückgabe reserviert und mussfreigehalten werden
- Die xmm Register werden nicht Vorrausgesetzt.

Es gibt folgende Möglichkeiten:

edi:esi:edx:eax
        Vorteil: Logische Erweiterung zu 64 bit
   Nachteil: Verletzung der "Nur eax, ecx, edx und der Gleitkomma dürfen verändert werden"-Regel.

st(1):st(0) {64 bit Integer lassen sich sicher in Gleitkommaregister laden.}
   Vorteil: Die Register bleiben frei.
   Nachteil: Daten können quasi nur direkt in den Speicher kopiert werden.

Speicherstelle mit Pointer in eax
   Vorteil: Die Register bleiben frei, Kompatibel zur Übergabe von structs
   Nachteil: Es muss zuerst eine geeignete Speicherstelle reserviert werden.

Ich wollt mal fragen, was ihr da für das beste haltet.
« Letzte Änderung: 30. October 2011, 20:24 von Sannaj »

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 30. October 2011, 18:17 »
Wenn du die General Purpose Register dafür verwendest, ist das erste, was du auf IA-32 mit den Werten machen musst, sie auf den Stack zu schreiben, weil du z.B. vor der Weiterverarbeitung eine andere Funktion aufrufen willst, oder aus anderen Gründen von Registerdruck betroffen bist. Deswegen bist du am besten aufgehoben, wenn du die Werte immer im Speicher hältst. Auf dem Stack ist ja genug Platz.

Ganz davon abgesehen halte ich 128-Bit-Integer-Arithmetik ohne CPU-Unterstützung für wenig sinnvoll. Hast du irgendwelche Anwendungsfälle dafür gefunden, die den Aufwand rechtfertigen?
« Letzte Änderung: 30. October 2011, 23:02 von Jidder »
Dieser Text wird unter jedem Beitrag angezeigt.

erik.vikinger

  • Beiträge: 1 277
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 31. October 2011, 15:44 »
Hallo,


wenn du diesen Rückgabewert auf dem Stack abliefern möchtest musst Du noch definieren wer diesen Stack alloziert und wer ihn frei gibt. Ich würde ja vorschlagen das beides der Caller machen muss und Du anstatt diesen Wert als Rückgabewert zurück lieferst der Caller einen Pointer als versteckten Parameter mitgeben muss, das hat einige Vorteile: das Funktioniert auch mir vararg-Funktionen, bei der extremen Registerknappheit von x86 macht es IMHO keinen Sinn sowas in den Registern zu übergeben und der Caller muss dafür nicht zwangsläufig den Stack benutzen sondern könnte z.B. den Pointer den er selber bekommen hat (weil sein Rückgabewert eben genau dieser Wert ist) benutzen. Mit dieser Vorgehensweise hätte der Code-Generator im Compiler noch einige Freiheitsgrade bei der Optimierung, er könnte z.B. feststellen das dieser 128Bit-Integer unmittelbar hinter dem Funktionsaufruf im Caller gleich verwendet wird und für diese Funktion die Aufrufkonvention ändern (falls es sich um eine statische Funktion handelt oder er bei der LTO feststellt das alle Aufrufe davon profitieren würden).

Ganz generell solltest Du die Aufrufkonvention nicht als unumstößliche Konstante sondern als flexible Arbeitsgrundlage für den Compiler betrachten, er wird, wenn er es für richtig hält, auch davon abweichen. Ich hab z.B. lange darüber nachgedacht ob die Flags mit gesichert werden sollen oder nicht, schlussendlich bin ich zu der Überzeugung gelangt das es recht egal ist was dazu die Aufrufkonvention vorschreibt solange das keine zu arge Bremse darstellt (es gibt ja auch einige Funktionsaufrufe wo der Compiler sich doch exakt an die Aufrufkonvention halten muss). Bei den Flags hab ich mich dazu entschieden das die per Default als Caller-Save/volatile deklariert sind da es wohl nur selten erforderlich ist sowas über einen Funktionsaufruf hinweg zu erhalten und es so auch leichter ist die Flags als Parameter/Rückgabewert zu benutzen (könnte eventuell beim Caller ein CMP-Befehl ersparen wenn der Rückgabewert nicht als 0 oder 1 in eax sondern als 0 oder 1 im Carry-Flag liegt).


Grüße
Erik
Reality is that which, when you stop believing in it, doesn't go away.

Sannaj

  • Beiträge: 103
    • Profil anzeigen
Gespeichert
« Antwort #3 am: 01. November 2011, 18:46 »
Naja, bei OS-def, Eigenen Programm Strukturen oder bei jeglichen Runtime Lib Krempel kann man in der Tat, die Aufrufkonvention über den Haufen werfen, da diese eh nur intern verwendet werden, aber extern ist zumindest optional eine gescheite C Kompatibilität (cdecl), wenn nicht sogar eine Kompatibilität mit stdcall und der C++-namespace/Overload Convention sinnvoll, sonst wird's schwer, irgendwelche externen Bibliotheken zu nutzten.

Zu der Sache mit dem 128 bit Integer und Quad Float. Ich habe mich entschlossen (zumindest auf dem x86-32), beide Datentypen auf dem Stack zugeben (auf [esp] nach Rückkehr von der Unterfunktion) über den Stack zurück zu geben, wobei der entsprechende Speicherplatz zuvor von der Aufrufenden Funktion reserviert werden muss (Wer den Restlichen Stack freigibt, entscheidet die Aufrufende Funktion. Beide Datentypen sind ohnehin ehr als Puffer für die Zukunft gedacht und weniger zum Produktiven Einsatz, (besonders bei dem 128 bit Integer).

erik.vikinger

  • Beiträge: 1 277
    • Profil anzeigen
Gespeichert
« Antwort #4 am: 04. November 2011, 19:54 »
Hallo,


dank LTO können moderne Compiler auch die Interfaces von Librarys usw. optimieren, aber natürlich nur wenn man auch ein statisch gelinktes Executable erzeugen lässt, theoretisch könnte das aber auch noch der Executable-Loader im OS machen. Das einzigste Interface was IMHO wirklich nicht vom Compiler optimiert werden kann sind die Syscalls.

Die Übergabe von großen Objekten auf dem Stack ist (bei CPUs mit chronischer Registerknappheit) eine gute Idee aber diese Position gleich festzunageln halte ich trotz allem für ungeschickt, natürlich würde ein verstecktes Parameter dafür beim Aufruf wieder ein wertvolles Register kosten aber dafür ergeben sich einige andere Optimierungen weil so nicht das Stack-Layout unmittelbar vor dem Call-Befehl festgelegt ist. Ich würde per Default lieber eine möglichst flexible Variante bevorzugen und den Compiler dann beim Optimieren sich eventuell selber beschränken lassen (wenn er merkt das er die Flexibilität nicht benötigt), andersherum dürfte für den Compiler schon schwieriger werden.


Mir ist noch was aufgefallen :
- ecx ist für die Fehlerrückgabe reserviert und mussfreigehalten werden
Ich rate jetzt mal das Du damit auf das Behandeln von SW-Exceptions anspielst. Eigentlich sind die C++-Leute recht stolz darauf das die meisten Features nur dann etwas kosten wenn man sie auch benutzt womit in dem konkreten Fall gemeint ist das eine Funktion die zwar ihrerseits Funktionen aufruft die Exceptions werfen können aber selber keine Exceptions benutzt (also weder try noch catch oder throw enthällt) auch keinen Overhead für das Durchleiten der Exceptions bekommen darf. Wenn Du per Default immer ein Register reservierst das eigentlich auch für nützliche Dinge verfügbar sein könnte entspricht das meiner persönlichen Meinung nach nicht dieser Philosophie. Wie Du das in Deinem Compiler handhaben möchtest ist natürlich Deine freie Entscheidung aber ich finde hier sollte noch mal nachgedacht werden.


Grüße
Erik
Reality is that which, when you stop believing in it, doesn't go away.

Sannaj

  • Beiträge: 103
    • Profil anzeigen
Gespeichert
« Antwort #5 am: 06. November 2011, 15:02 »
Naja, mir ist grad aufgefallen, das das mit der Stackuebergabe gar nicht in meinem Konzept stand, ich hatte eine durch einen Pointer (Rueckgabe in eax) beschriebene Stelle im Speicher in Augen. (Wofuer 16 byte in der Runtime-lib Reserviert sind.

Zu der Sache mit der Fehlerrueckgabe, da ich mich mit C++ nicht wirklich auskenne, hab ich keine Ahnung was SW-Exeptions sind. Ich hatte eigentlich an eine andere Idee im Sinn. Im Default-Fall wird ecx unbestimmt von einer Funktion zuruekgeeben. Im Fehlerfall muss die Funktion die Ruecksprungaddresse mit 0 ueberschreiben und den Fehlerwert in ecx zurueckgeben. (eax & co. sollten trozdem irgenteinen mehr oder weniger Sinnvollen Inhalt enthalten.) Das ist zwar ein bisschen aufwaendig, aber es ist nur im Fehlerfall noetig. Wenn der Caller den Fehler nicht versteht, oder ignoriert, ist das nicht schlimm, weil er dann ecx ignuriert und nur eax & co. beachtet.

erik.vikinger

  • Beiträge: 1 277
    • Profil anzeigen
Gespeichert
« Antwort #6 am: 06. November 2011, 15:46 »
Hallo,


ich hatte eine durch einen Pointer (Rueckgabe in eax) beschriebene Stelle im Speicher in Augen. (Wofuer 16 byte in der Runtime-lib Reserviert sind.
Das geht auf jeden Fall in die Hose, wenn der Platz in der Runtime-Lib nur ein einziges mal vorhanden ist dann ist Dein Programm nicht multithreading tauglich. Wenn Du anderen Speicher benutzen möchtest dann benötigst Du im Endeffekt eine Art malloc (was der Callee aufruft) ein ein free (was der Caller aufruft). Das der Callee dem Caller einen Pointer gibt wo er das Ergebnis hingelegt hat führt IMHO grundsätzlich zu unlösbaren oder überteuerten Problemen.

Ich hatte eigentlich an eine andere Idee im Sinn.
Dann erzähl doch mal. Das was Du da geschrieben hast klingt auf jeden Fall nicht nach einer Methode die von C oder C++ oder einer anderen üblichen Programmiersprache unterstützt wird. Ein Compiler-Feature das man nur nutzen kann wenn man in Assembler programmiert nützt auch nichts da man dafür ja keine Hochsprache benötigt. Für welche Programmiersprache willst Du überhaupt einen Compiler bauen?

Im Default-Fall wird ecx unbestimmt von einer Funktion zuruekgeeben.
Trotzdem ist ein Register weg das man auch sinnvoll nutzen könnte. Das entspricht auf jeden Fall nicht der Philosophie das Features die nicht benutzt werden auch nix kosten dürfen.

Im Fehlerfall muss die Funktion die Ruecksprungaddresse mit 0 ueberschreiben
Aha, und wo führt dann das RET hin?
Entschuldige Bitte die direkte Frage aber ein erfahrener Assembler-Programmierer bist du nicht gerade oder?

Einen Fehler zurück zu melden den der Caller nach belieben ignorieren darf ist auf jeden Fall keine strukturierte Vorgehensweise, der Callee meldet den Fehler doch nicht ohne Grund und wahrscheinlich sind die normalen Rückgabewerte dann auch unbrauchbar (schließlich signalisiert ein Fehler doch für gewöhnlich das die Funkion nicht korrekt bis zum regulären Ende durchlaufen konnte).


Grüße
Erik
Reality is that which, when you stop believing in it, doesn't go away.

Sannaj

  • Beiträge: 103
    • Profil anzeigen
Gespeichert
« Antwort #7 am: 06. November 2011, 21:52 »
ich hatte eine durch einen Pointer (Rueckgabe in eax) beschriebene Stelle im Speicher in Augen. (Wofuer 16 byte in der Runtime-lib Reserviert sind.
Das geht auf jeden Fall in die Hose, wenn der Platz in der Runtime-Lib nur ein einziges mal vorhanden ist dann ist Dein Programm nicht multithreading tauglich. Wenn Du anderen Speicher benutzen möchtest dann benötigst Du im Endeffekt eine Art malloc (was der Callee aufruft) ein ein free (was der Caller aufruft). Das der Callee dem Caller einen Pointer gibt wo er das Ergebnis hingelegt hat führt IMHO grundsätzlich zu unlösbaren oder überteuerten Problemen.
Das mit dem Multitasking hab ich nicht bedacht, danke für den Hinweis. Ich möchte eigentlich vermeiden, dass man für jede Rückgabe von (abgesehen von ganz einfachen Datentypen) malloc() und free() aufrufen muss.

Ich hatte eigentlich an eine andere Idee im Sinn.
Dann erzähl doch mal. Das was Du da geschrieben hast klingt auf jeden Fall nicht nach einer Methode die von C oder C++ oder einer anderen üblichen Programmiersprache unterstützt wird. Ein Compiler-Feature das man nur nutzen kann wenn man in Assembler programmiert nützt auch nichts da man dafür ja keine Hochsprache benötigt. Für welche Programmiersprache willst Du überhaupt einen Compiler bauen?

Im Default-Fall wird ecx unbestimmt von einer Funktion zuruekgeeben.
Trotzdem ist ein Register weg das man auch sinnvoll nutzen könnte. Das entspricht auf jeden Fall nicht der Philosophie das Features die nicht benutzt werden auch nix kosten dürfen.

Was für eine Fehlerbehandlung schlägst du den vor? ecx wird bei den gängigen Konventionen auch unbestimmt zurückgegeben. (D.h. es kann in der Subroutine nach belieben verwendet werden, und brauch nicht auf irgendeinen Finalwert gebracht werden.

P.S Ich plane eine Compiler für eine eigene Sprache (Aurora), warscheinlich auf LLVM oder i386-Assembler Basis.

Im Fehlerfall muss die Funktion die Ruecksprungaddresse mit 0 ueberschreiben
Aha, und wo führt dann das RET hin?
Entschuldige Bitte die direkte Frage aber ein erfahrener Assembler-Programmierer bist du nicht gerade oder?

Das hab ich schon bedacht, dass man die Rücksprungadresse vorher sichern und manuell anspringen muss.

Einen Fehler zurück zu melden den der Caller nach belieben ignorieren darf ist auf jeden Fall keine strukturierte Vorgehensweise, der Callee meldet den Fehler doch nicht ohne Grund und wahrscheinlich sind die normalen Rückgabewerte dann auch unbrauchbar (schließlich signalisiert ein Fehler doch für gewöhnlich das die Funkion nicht korrekt bis zum regulären Ende durchlaufen konnte).
Wahrscheinlich lass ich die betroffenen Register mit irgendeinem Standartwert z.B. "0" füllen. (Oder der edx mit der Rücksprungadresse (auch bei int64), was die Fehlerrückkehrroutine vereinfachen würde.)

erik.vikinger

  • Beiträge: 1 277
    • Profil anzeigen
Gespeichert
« Antwort #8 am: 07. November 2011, 22:06 »
Hallo,


Ich möchte eigentlich vermeiden, dass man für jede Rückgabe von (abgesehen von ganz einfachen Datentypen) malloc() und free() aufrufen muss.
Das solltest Du nicht nur möchten das wirst Du müssen. Wenn der normalen Compiler-generierte Code von irgendeiner Runtime-Library (die ja gar nicht zwingenst vorhanden sein muss, ich denke da nur an Mikro-Controller oder andere Embedded-Sachen usw.) abhängt dann ist Dein Design eindeutig Kaputt. Sowas kann man eventuell für spezielle Sachen machen, die dann explizit per Compiler-Parameter freigeschallten werden müssen, aber nicht für den ganz normalen Code.

Was für eine Fehlerbehandlung schlägst du den vor?
Keine Ahnung, das hängt doch in erster Linie davon ab was Deine Programmiersprache für Features anbieten können soll. Erst nachdem Du das konkret festgelegt hast kannst Du Dir überlegen wie Dein Compiler das umsetzen soll. Natürlich muss man das auch in die andere Richtung betrachten, es ist nicht sehr hilfreich wenn Deine Programmiersprache Features anbieten will die Dein Compiler nicht vernünftig in Code umsetzen kann.

Ich plane eine Compiler für eine eigene Sprache (Aurora), warscheinlich auf LLVM oder i386-Assembler Basis.
Ich würde LLVM bevorzugen, der optimiert ganz gut (inklusive LTO) und dürfte sicher besser sein als alles was ein einzelner Programmierer mit vertretbaren Aufwand hinbekommen kann.

Das hab ich schon bedacht, dass man die Rücksprungadresse vorher sichern und manuell anspringen muss.
Und wohin sichern? Es gibt doch effektiv nur den Stack, das ist der einzigste Speicher von dem sich der Compiler bedienen kann ohne von irgendetwas anderem abhängig zu sein. Wenn Du eh die Rücksprungadresse nur an eine andere Stelle auf den Stack packst dann bleibt immer noch die Frage: wozu? Lass die Rücksprungadresse doch einfach da wo sie ist und nimm das RET was die CPU schon hat, dann musst Du auch nichts emulieren.


Grüße
Erik
Reality is that which, when you stop believing in it, doesn't go away.

Sannaj

  • Beiträge: 103
    • Profil anzeigen
Gespeichert
« Antwort #9 am: 07. November 2011, 22:16 »
Das hab ich schon bedacht, dass man die Rücksprungadresse vorher sichern und manuell anspringen muss.
Und wohin sichern? Es gibt doch effektiv nur den Stack, das ist der einzigste Speicher von dem sich der Compiler bedienen kann ohne von irgendetwas anderem abhängig zu sein. Wenn Du eh die Rücksprungadresse nur an eine andere Stelle auf den Stack packst dann bleibt immer noch die Frage: wozu? Lass die Rücksprungadresse doch einfach da wo sie ist und nimm das RET was die CPU schon hat, dann musst Du auch nichts emulieren.

Ich dachte da an:
xor edx, edx
xchg edx, [esp]
add esp, 4
jmp edx

oder (wenn man die Register bewahren soll.)
push eax
xor eax, eax
xchg eax, [esp+4]
xchg eax, [esp]
ret 4
« Letzte Änderung: 07. November 2011, 22:19 von Sannaj »

erik.vikinger

  • Beiträge: 1 277
    • Profil anzeigen
Gespeichert
« Antwort #10 am: 07. November 2011, 22:23 »
Hallo,


Ich dachte da an:
Das scheint zwar valider Assembler-Code zu sein aber wozu das ganze? Ich sehe darin keinen Sinn.


Grüße
Erik
Reality is that which, when you stop believing in it, doesn't go away.

Sannaj

  • Beiträge: 103
    • Profil anzeigen
Gespeichert
« Antwort #11 am: 07. November 2011, 22:36 »
Ich möchte halt eine Möglichkeit haben, meine Fehler zu erkennen, ohne im Normalfall irgendwie darauf zu achten. Das einzige, worauf ich mich verlassen kann, ist, das die Rücksprungadresse einer Funktion im Normalfall einen vernünftigen Wert (sprich != 0) besitzt. Der Folgende Code würde im Fehlerfall anstelle von "ret" aufgerufen werden. Er überschriebt die Position der Rücksprungadresse mit 0 und kehrt dann trotz allem zur aufrufenden Funktion zurück. Dieser kann nun erkennen, dass ein Fehler aufgetreten ist, weil die Position der Rücksprungadresse (jetzt esp-4) null ist und eine Fehlerbehandlung einleiten. (Die dann z.B. ecx auswertet.)

Als Alternativkonzept hab ich mir überlegt, das die Funktion einige Informationen über die Position der Fehlerbehandlungsroutine besitzt, (z.b. das diese sich z.B. 16 Byte hinter der Rücksprungadresse befindet oder an einer Addresse, die der Funktion in irgendeinem Register oder Parameter mitgegeben wurde.

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #12 am: 07. November 2011, 22:46 »
Mal eine kurze Zwischenfrage: Wie weit hast du dich mit den Exception-Behandlungen, die andere Compiler verwenden, auseinander gesetzt? Wenn die Antwort lautet: "Gar nicht", "Wenig" oder "Hab ich nicht verstanden", dann solltest du das ändern.
Dieser Text wird unter jedem Beitrag angezeigt.

erik.vikinger

  • Beiträge: 1 277
    • Profil anzeigen
Gespeichert
« Antwort #13 am: 07. November 2011, 22:56 »
Hallo,


kann nun erkennen, dass ein Fehler aufgetreten ist, weil die Position der Rücksprungadresse (jetzt esp-4) null ist und eine Fehlerbehandlung einleiten.
Dir ist bewusst das [esp-4] außerhalb des Stacks ist? Wenn zwischen Deinem emuliertem RET und der Auswertung irgendein IRQ o.ä. dazwischen kommt wird der Stack womöglich mit was anderem überschrieben. Du solltest Dich nur auf Speicher verlassen der auch wirklich Dir gehört.

Ansonsten finde ich den Einwand von Jidder durchaus angebracht.


Grüße
Erik
Reality is that which, when you stop believing in it, doesn't go away.

Sannaj

  • Beiträge: 103
    • Profil anzeigen
Gespeichert
« Antwort #14 am: 07. November 2011, 23:05 »
Naja gut, dann muss ich mir was anderes einfallen lassen. Kann mir jemand einen Tipp geben, wo man die von Jidder erwähnten Infos findet. Ich hab nämlich ein bisschen erfolglos recherchiert.

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #15 am: 08. November 2011, 00:02 »
Ich weiß es auch nicht so genau, weil das ein Implementierungsdetail ist, das sich alle 5 Jahre ändert. Das Stichwort, das ich googeln würde (neben "Exception Handling") wäre "Stack Unwinding". Ansonsten wäre mein Ratschlag: Vielleicht solltest du erstmal einen C Compiler schreiben, bevor du dich an C++ wagst.
Dieser Text wird unter jedem Beitrag angezeigt.

Sannaj

  • Beiträge: 103
    • Profil anzeigen
Gespeichert
« Antwort #16 am: 08. November 2011, 22:11 »
Naja, ich hab mir das mal durchgelesen. Ich habe übrigens nicht vor, eine C++ Compiler zu schreiben. Das wäre übrigens grundsätzlich eine schlechte Idee, denn C++ ist nicht nur eine der komplexesten Programmiersprachen überhaupt, sondern auch noch ein Superset von C, sodass die meisten C++-Compiler als C Compiler begonnen haben. Wie oben erwähnt, habe ich vor eine eigene Programmiersprache zu erstellen.

Zum Exeption Handling. Ich habe mir noch mal ein bisschen was dazu durchgelesen. Das Problem ist, die Adresse, an welcher der Exeption Handler steht, an den Fehlerbehandlungsfunktion der Laufzeitroutine zu übergeben. Dazu schlägt http://en.wikipedia.org/wiki/Exception_handling#Exception_handling_implementation verschiedene Möglichkeiten vor. Ich halte das statische Sinnvoll, bei der der Exeption Handler an Hand einer Addresse (ich gehe davon aus, das es sich um die Rücksprungadresse handelt) und einer vorgefertigten Address-Frame-Table, in der dann die Adressbereiche aller try-Blöcke eingetragen sind, die Adresse des passenden Händlers ermittelt. Natürlich muss auch das Stack Unwinding durchgeführt werden, aber ich glaube, das ist er Nebensache, wenn man weiß, was aufgeräumt werden muss. Ich denke die Funktion sollte den Teil des Stacks über der Rücksprungadresse vor Aufruf des Error-Handlers selbst aufräumen, der Handler erledigt dann den Rest.

Sannaj

  • Beiträge: 103
    • Profil anzeigen
Gespeichert
« Antwort #17 am: 10. November 2011, 07:51 »
Das Problem ist halt, wie bekomme ich es hin, das die Tabellen aller Teilmodule zu einer einzigen Größen Exeption-Frame Tabelle zusammen gelinkt werden?

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #18 am: 10. November 2011, 10:56 »
Ohne den Kontext genauer gelesen zu haben: Würde alle Teiltabellen in dieselbe Section stecken (in der natürlich sonst nichts anderes ist) dein Problem lösen?
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

Sannaj

  • Beiträge: 103
    • Profil anzeigen
Gespeichert
« Antwort #19 am: 10. November 2011, 14:02 »
Das Hängt davon ab, was ich über das Section weiß.
- Die Sektions müssen alle zu einer Sektion zusammengefasst sein, sodass der Inhalt direkt nacheinander Folgt. (Die Reihenfolge ist egal.)
- Die Startadresse und Größe der Sektion muss bekannt sein. (Für das ausführende Programm)

 

Einloggen