Lowlevel
Lowlevel => Lowlevel-Coding => Thema gestartet von: scales of justice am 31. March 2006, 09:31
-
Hallo,
ich habe einen Kernel aus C und Assembler gemacht, indem ich beide zusammen gelinkt habe
aber wenn ich jetzt in ld (der Linker) den Einsprungpunkt auf 1000:0000 setze (da wird der Kernel hingeladen) stimmt der ja nur für den Assemblerkernel
der CKernel ist ja 512 bytes hinter dem assemblerkernel
deswegen funktioniert das ganze natürlich nicht
da die Sprünge des CKernels alle ins Nirvana führen
wie stelle ich das jetzt richtig ein?
-
Du musst natürlich erstmal aus dem ASM und dem C-File jeweils einen Object-File machen - vermutlich tust du das schon. Im C-File hast du z.B. diesen Code:
void main()
{
/* Do something */
}
Im Asm-File kannst du jetzt mit
extern main ; Unter Windows musst du _main nehmen
die Funktion importieren. Das heißt im Asm-File kannst du mit dem Namen main bzw. _main dorthin springen:
call main ; Oder unter Windows _main
Zuletzt linkst du einfach die Object-Files zusammen und das wars.[/code]
-
ich versteh den Zusammenhang zwischen meiner Frage und deiner Anwort nicht
ich weiß wie man aus Assembler C-Funktionen aufruft und umgekehrt
aber wenn ich mit ld die Startadresse beispielsweiße auf 1000:0000 setze
wird im Assemblerkernel, der ja wirklich an 1000:0000 anfängt alles richtig adressiert
im CKernel, der erst an 1000:0200 anfängt aber natürlich nicht, da müsste ja zu allen Adressen 200h dazugerechnet werden, also bräuchte ich soetwas wie eine org Funktion, nur eben für C
ich hab mir auch schon das CKernel Tutorial von Tee-Jay angeguckt, aber das funktioniert ja nicht, wird mir also nicht weiterhelfen
-
wenn du assemblerkernel und ckernel mit ls linkst, dann sieht er das (unabhängig von der größe der einzelnen dateien) als ein programm an. diesem gibt er dann deine angegebene startadresse und adressiert entsprechend alle variablen, funktionen, etc.
dafür ist das linken ja da.
-
genau das mein ich ja
wenn den Assemblerkernel assembliere, geht nasm davon aus, dass er bei 0 anfängt, deswegen stell ich manuell das DS und ES register um:
cli
mov ax, cs
mov ds, ax
mov es, ax
sti
dann funtkioniert der Assemblerkernel
aber der CKernel ist bei 1000:0200, der compiler denkt aber nun auch er wäre bei 0000:0000, das Segment wird ja schon auf 1000 gestellt, also denkt er im Endeffekt er ist bei 1000:0000
deswegen muss ich ja das Offset erst umstellen bevor etwas funktionieren kann
das wär auch nicht das Problem,
ich will aber aus dem CKernel Funktionen im Assemblerkernel ausführen
das heißt ich msste die Register die ganze Zeit wieder umstellen
Im Endeffekt muss ich dem Compiler der den CKernel compiliert (gcc) klar machen, dass alle seine Daten 200h bytes weiter hinten liegen, als er eigentlich denkt, bei nasm wär das mit
org 200
erledigt
und so einen Befehl bräucht ich halt für gcc, bzw. für as (as ist der Assembler den gcc nach dem compilieren benutzt um das ganze zu assemblieren)
EDIT:
as unterstützt sogar org, allerdings funktioniert das Programm trotzdem nicht
-
Irgendwie versteh ich das Problem nicht... du hast Funktionen im C-Kernel, die du im ASM-Teil importieren kannst und dann aufrufen kannst. Umgekehrt geht das auch. Mit "global name" exportierst du Funktionen die in den Asm-Files liegen. In beide Richtungen funktioniert das auch mit Variablen. Das heißt du musst dich gar nicht um irgendwelche Adressen kümmern, sondern einfach die Namen der Funktionen/Variablen benutzen - für solche Zwecke wurden ja die Linker geschaffen.
-
nein, so einfach geht es eben nicht, das ist doch das Problem an der Sache
ich hab aber in nem neuen Thema den Quellcode gespostet, wenn du ihn ausprobierst wirst du sehen das es nicht geht