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