Autor Thema: "Kleine" Frage zu API  (Gelesen 4707 mal)

RedEagle

  • Beiträge: 244
    • Profil anzeigen
    • RedEagle-OperatingSystem - Projekt
Gespeichert
« am: 20. December 2006, 18:01 »
Wie geht das mit der API genau??
Also ich möchte keine Interrupts benutzen, sonder Calltables (oder wie das heißt)

bsp.:
fnc_kbd_getlastkey_cv_a#AFFE707

fnc_kbd_getlastkey = Funktionsname
_cv = Rückgabewert / parameter
_a = Version (falls es irgendwann mal eine ähnliche mit gleichen namen geben sollte
# = signalisiert das ende des namens, und beging der Adresse
AFFE707 = Adresse der Funktion (natürlcih nicht ASCII-Codiert)

Kann man das so machen??
Wenn ja, wie sage ich meinem Kompiler, das er mir so eine Liste erstellt??
Oder soll ich es zur laufzeit machen??

Korona

  • Beiträge: 94
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 21. December 2006, 17:13 »
Das was du da beschrieben hast, ist nur ein Verfahren, die Funktionsnamen zu codieren, so dass Überladen von Methoden möglich wird, z.B. in C++ oder Java. Dies dient aber lediglich dazu, die Methoden beim Kompilieren und für den Assembler auseinanderzuhalten. Mit dem späteren Aufruf hat das nicht sehr viel zu tun.

Um Kernelfunktionen aufzurufen, musst du Interrupts oder ähnliches verwenden, du musst ja schließlich von Ring3 in Ring0 switchen und das ist durch einfache Calls nicht möglich.

Termite

  • Beiträge: 239
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 21. December 2006, 18:01 »
Wieso brauch ich im code für das überladen von Methoden so eine hässliche codierungen? das kann der compiler geschickter lösen. Normale methoden werden direckt angesprungen. Bei überladenen wird Indireckt gesprungen, über eine sprungtabelle, die das Object ( bzw die datenstrucktur) mitbringt. C++ hat da nur wegen der mehrfachvererbung ein paar hässliche gemeinheiten auf lager. Auser es währe part von Reflection in C++ ( womit ich bisher nichts zu tun hatte)

Solche namen kommen mehr eher aus libs bekant vor bzw dlls. da mus das system ja anhand der Namen die passende funktionsadresse ermitteln können.

aber was soll ein assembler damit zu tun haben?

gruss

RedEagle

  • Beiträge: 244
    • Profil anzeigen
    • RedEagle-OperatingSystem - Projekt
Gespeichert
« Antwort #3 am: 21. December 2006, 18:20 »
offensichtilich wurde mein anliegen falsch verstanden...

Fals ich des im Kernel mache:
void createlist()
{
 BYTE *liste;
 liste = 0x02000000;

 strcpy(liste,"funktion01");
 list+= sizeof("funktion01");

 *(DWORD*)liste = funktion01;
 return;
}

Das ganze drumrum (fnc_kbd_, _cv_a#) muss natürlich nicht sein, hätte ich aber gerne.

Interrupts möchte ich dafür nicht so gerne nutzen.

ps.: Fals es interessiert: Es ist ein singletasking system, wobei die Laufende Anwendung kernelrechte hat (und unbeding haben soll)

Korona

  • Beiträge: 94
    • Profil anzeigen
Gespeichert
« Antwort #4 am: 21. December 2006, 18:28 »
Der Kompiler codiert die Methodennamen ganz einfach auf diese Weise. Das Nicht-Statische Methoden einer Klasse indirekt gecallt werden ist klar, ich sagte ja, das hat nur wenig mit dem Aufruf zu tun.

Angenommen ich habe zwei Funktionen:
int add(int a, int b);
double add(double a, double b);
Dann dient diese Codierung dazu, das der Compiler und der Assembler diese Methoden unterscheiden können, da der Namen von beiden ja gleich ist.

EDIT:
Zitat
Solche namen kommen mehr eher aus libs bekant vor bzw dlls. da mus das system ja anhand der Namen die passende funktionsadresse ermitteln können.
Ja, das gleiche muss der Assembler und der Linker aber auch bei nicht-lib Funktionen machen ;) Dazu dient diese Codierung ja.

@RedEagle
Wenn deine Anwendung im Kernel-Mode läuft, kannst du einfach normale Calls benutzen, indem du deine Funktionen in der API als extern deklarierst und dann die Symbole beim Laden relocatest. Wie das geht sollte in deiner Beschreibung zu deinem Executableformat stehen. (Wie es bei ELF geht ist z.B. sehr gut in der Dokumentation zu ELF beschrieben.)
« Letzte Änderung: 21. December 2006, 18:35 von Korona »

Termite

  • Beiträge: 239
    • Profil anzeigen
Gespeichert
« Antwort #5 am: 22. December 2006, 09:38 »
Bin jetzt gerae etwas total verwirrt.

Meine bisherigen vorstellungen eines Build prozesses.

1. Compiler erstellt  ausmeinem Code eine Object datei, in der beretis eine art binärcode enthält nur ohne irgendwelche Addressen, Anstelle der Addressen sind Platzhalter eingetragen, die den Funktionsnamen, Variablennamen entsprechen.

2. Der Assembler tut genau das gleiche wie ein compiler nur als eingabesprache wird ASM - Code verwendet

3. Der linker bindet die ganzen Objectdateien zusammen. Er vergibt für die ganzen platzhalter die passenden addressen und ersetzt diese. Als ergebnis kommt eine ausführbare datei raus.

Der Compiler kann auch als zwischenschritt Assemblercode generieren.

Die Funktionsnamen und Variablennamen verschwinden nach dem linken aus dem Binary code. Wozu sollten die noch von nöten sein. ( ausnahme refectoring ) [edit] zeit für Wheinachten. ich meinte natürlich Reflaction.

Oder als weitere Ausnahme, wenn eine LIB / DLL generiert werden soll. Hier müssen die öffentlich bekanten Funktionen ja ansprechbar sein. Entweder geschieht das während der laufzeit des systems, oder bereits beim linken.

gruss
« Letzte Änderung: 22. December 2006, 10:30 von Termite »

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #6 am: 22. December 2006, 10:16 »
Die Funktionsnamen und Variablennamen verschwinden nach dem linken aus dem Binary code. Wozu sollten die noch von nöten sein. ( ausnahme refectoring )
Du machst Refactoring mit Binaries? Krank... ;) Ich hätte jetzt eher gesagt, als Debuginformation können sie drinbleiben (je nach Compileroption).
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

Termite

  • Beiträge: 239
    • Profil anzeigen
Gespeichert
« Antwort #7 am: 22. December 2006, 10:29 »
Moin

Ich hab nicht gesagt das ich sowas mache. Ich hab nur gehört das manche c++ kompiler nen passenden schalter anbieten sollen, um sowas machen zu können. ( Ich persönlich bin immer davon ausgegangen, wenn ich sowas in c/c++ haben will, muss ich das selber machen, gegengeprüft hab ich das bisher noch nicht) und um sowas machen zu können, benötige ich die passenden informationen. Ohne die sowas gar nicht möglich währe.

am äh ja es ist zeit für Urlaub. ich meinte Reflaction nicht Refactoring.

gruss.

ps. der count down läuft t-7:30

Korona

  • Beiträge: 94
    • Profil anzeigen
Gespeichert
« Antwort #8 am: 22. December 2006, 11:47 »
Der Kompiler generiert ASM Code (Oder direkt Objektdateien, ist egal). Der enthällt natürlich keine Addressen, sondern Labels/Symbole etc. Wenn jetzt 2 oder mehr Methoden den gleichen Namen haben: (z.B. int add(int, int); und double add(double, double);) dann werden diese Namen auf eine bestimmte Weise codiert, weil sie ja sonst vom Assembler und Linker nicht zu unterscheiden wären (die wissen ja nichts von den Parametern etc.). Der Linker nimmt den Objektcode, fügt ihn zusammen und trägt die Adressen ein. Dazu ist in der Objektcode Datei eine Tabelle, in der steht, an welche Stelle innerhalb des Text-Segments die Addresse von welchem Symbol kommt. Der Linker geht diese Tabelle/Liste einfach durch und ersetzt dann die entsprechenden Stellen im Code durch die Addressen der Symbole.

RedEagle

  • Beiträge: 244
    • Profil anzeigen
    • RedEagle-OperatingSystem - Projekt
Gespeichert
« Antwort #9 am: 30. December 2006, 16:08 »
Ich habe mir mal über ein anderes Konzept gedanken gemacht.:
die main-Funktion einer "normalen" Anwendung:
DWORD main(DWORD interface, char* arg)

In "interface" steht dann eine adresse einer Funktionb drin, mit der man mit dem OS "Kommunizieren" kann
Prototyp:
DWORD os(DWORD command, DWORD argument);

Und über die os-Funktion kann man sich dann alle möglichen adressen von Variablen / Funktionen holen, die man braucht, oder auch andere informationen an das system geben, bzw vom system holen...

Korona

  • Beiträge: 94
    • Profil anzeigen
Gespeichert
« Antwort #10 am: 02. January 2007, 19:13 »
Wenn deine Anwendung Kernelrechte hat, kannst du einfach über normale Calls Kernelfunktionen aufrufen:

Anwendung:

void main() {
kernel_draw_something();
kernel_allocate_some_memory();
kernel_do_something_else();
}

Du musst dann halt nur das Executable Format richtig parsen und zur Laufzeit die Calls linken.

 

Einloggen