Aus Assembler C-Funktion aufrufen



  • Sers,

    Also: Da das Interesse an Assembler gewachsen ist, wollte ich mal wieder was damit machen´.

    Hab jetzt einen Bootloader gemacht, der den Kernel läd.

    Um jetzt weiter zu machen, will ich mit C weiterprogrammieren. Wie ich dabei vorgehen sollte, (denk ich zu wissen) weiss ich.

    Ich zeig einfach mal ein wenig Code her:

    kernel.asm

    ; ------------------
    ; Externe Funktionen
    ; ------------------
    extern _main
    
    mov ax, 1000h
    mov ds, ax
    mov es, ax
    
    ; ------------
    ; Kernel Start
    ; ------------
    start:      
    	; Kernel starten 
    	call _main
    
    	; Reset     
    	jmp reset
    
    ; --------------------
    ; Unterprogramm: reset
    ; --------------------
    	reset:
    	db 0Eah
    	dw 0000h
    	dw 0FFFFh
    

    Jetzt die ckernel.c mit der main Funktion

    void main(void)
    {
    	getch();
    }
    

    Sodele, jetzt noch die input.c die getch zur Verfügung
    stellen soll:

    int getch(void)
    {
       int buf;
    
    	asm("mov $0x0, %ah");
    	asm("int $0x16");
    	asm("mov %al, buf");
    
       return buf;
    }
    

    So, vorgehen tu ich dann so:
    Die *.c Dateien hab ich in einem Projekt von Dev-Cpp.
    Projekttyp: Statische Bibliothek.
    Wenn ich kompiliere, erhalte ich die Bibliothek "bdOS.a"

    Weiterhin habe ich die Datei kernel.asm

    Das tu ich jetzt ohne Fehlermeldung so zusammenführen:
    nasm -f coff -o kernel.out -l bdOS.a kernel.asm

    Normalerweise sollte nach dem Bootvorgang (klappt wunderbar) der Kernel laden, die main() Funktion aufrufen, eine Taste einlesen und rebooten...

    Macht er aber nicht! Er bootet, läd Kernel und dann geht nix mehr, also er hängt irgentwie, aber ohne Auslastung, keine Ahnung.

    Wo ist der verdammte Fehler?!?!

    Hoffe ihr könnt mir helfen.
    ciao
    paranoiac 😃



  • Hast du mal gecheckt, ob dien Bootloader den Code wirklich an die gewünschte Stelle packt etc.? Trace doch mal z.B. mitm Bochs-Debugger durch.



  • Mmmh,
    Hab leider keine Ahnung von Bochs.
    Aber ich kann mal schnell den Bootloader noch hier reinpacken:

    org 0x7C00
    
    ; BL starten
    jmp start
    
    ; -----
    ; Daten
    ; -----
    iBootDrive	db 0
    szBootMsg00	db "- Bootloader [ bdOSLoader ] gestartet -",10,13,10,13,0
    szBootMsg01	db "Stack wird erstellt...",10,13,0
    szBootMsg02 	db "Kernel wird geladen...",10,13,0
    
    ; --------
    ; BL Start
    ; --------
    start:
    	; Bildschirm löschen
    	call cls
    
    	; Textausgabe
    	mov si, szBootMsg00
    	call _printstring	
    
    	; Stack aufbauen
    	mov si, szBootMsg01		; Info
    	call _printstring
    	cli
    	mov ax, 0x9000			; Adresse des Stack speichern
    	mov ss, ax      		; Stackadresse festlegen
    	mov sp, 0       		; Stackpointer auf 0 setzen
    	sti            
    
    	; Bootlaufwerk sichern
    	mov [iBootDrive], dl
    
    	; Kernel laden
    	mov si, szBootMsg02		; Info
    	call _printstring
    	call LoadKernel
    
    	; Shell aufrufen
    	mov ax, 1000h
    	mov es, ax
    	mov ds, ax
    	push ax
    	mov ax, 0
    	push ax
    	retf
    
    ; -------------------
    ; Unterprogramm - cls
    ; -------------------
    cls: 
    	mov ax, 600h
       	mov cx, 0h 
       	mov dx, 174fh
       	mov bh, 0h  
       	int 10h   
       	ret 
    
    ; ---------------------------
    ; Unterprogramm - PrintString
    ; ---------------------------
    _printstring:
    	mov ah, 0eh
    	mov bx, 7h
    	_printstringloop:
    		lodsb
    		int 10h
    		cmp al, 0h
    		je _printstringend
    		jmp _printstring
    	_printstringend:
    	ret
    
    ; --------------------------
    ; Unterprogramm - LoadKernel
    ; --------------------------
    LoadKernel:
    	; Reset des Bootlaufwerkes
    	push ds
    	mov ax, 0
    	mov dl, [iBootDrive]
    	int 13h
    	pop ds
    	jc LoadKernel			; Bei Fehler nochmal probieren
    
    	load:
    	mov ax,0x1000
    	mov es,ax
    	mov bx, 0
    	mov ah, 2
    	mov al, 5
    	mov cx, 2
    	mov dx, 0
    	int 13h
    	jc load
    	retn
    
    ; Auf 512 Byte auffüllen
    times 512-($-$$)-2 db 0
    dw 0AA55h
    

    Und nicht wundern....



  • Okay, dein Kernel liegt also ab 0x10000. Weiß der Linker das auch, dass die Adressen da anfangen müssen? Weil wenn der das nicht weiß, nimmt der die fürs Betriebssystem typischen Adressen schätze ich mal.



  • TriPhoenix schrieb:

    Okay, dein Kernel liegt also ab 0x10000. Weiß der Linker das auch, dass die Adressen da anfangen müssen? Weil wenn der das nicht weiß, nimmt der die fürs Betriebssystem typischen Adressen schätze ich mal.

    Mmmh, hört sich logisch an, aber wie sag ich ihm das jetzt??
    Sorry, aber ich hab leider nicht so viel Ahnung!



  • Hab noch mal ne allgeimeine Frage, ich hab ja mein bootloader.asm.
    Wie tu ich den jetzt assemblieren?!?!
    Bisher mit: nasm -f bin -o bootloader.o bootloader.asm
    Hab ich mit dem Kernel genauso gemacht.
    Da ich aber jetzt den Kernel aus der Bibliothek in *.c und der kernel.asm zusammensetze, dann ich für das assemblieren des Kernels nicht den Typ "bin" benutzen. auch nicht "coff". Da nehm ich jetzt "aout".

    Jetzt wird aber beides verschieden assembliert. Macht das was??
    Ich weiss es nicht, bitte sagt es mir!

    Danke!

    [wissen]TEsT[/wissen]
    Google: ASM



  • Also ich habs jetzt geschafft, dass er zum Kernel springt.
    Dabei hab ich die Sache mit C weggelassen zum Testen.

    Jetzt will ich das wieder mit rein nehmen und gehe so vor, dass ich alle *.c Dateien kompiliere:
    gcc -c -o 1.o 1.c
    gcc -c -o 2.o 2.c
    gcc -c -0 3-o 3.c

    Dann hab ich 3 *.o Dateien: 1.o 2.o 3.o

    Jetzt hab ich noch die Datei 4.asm, die ich so kompilier:
    nasm -f bin -o 4.o 4.asm

    Dann will ich alle zusammenfügen mit:
    gcc -o kernel.bin 1.o 2.o 3.o 4.o

    Aber es kommt dieser Fehler:
    4.o: file not recognized: File format not recognized

    Was zum Henker mach ich falsch?



  • Per nasm -f bin erzeugst du ein binary,. was keien Linkerinformationen enthält. Deswegen schriet der Linker dann. Nimm lieber elf oder coff, das evrsteht de Linker danna uch.



  • TriPhoenix schrieb:

    Per nasm -f bin erzeugst du ein binary,. was keien Linkerinformationen enthält. Deswegen schriet der Linker dann. Nimm lieber elf oder coff, das evrsteht de Linker danna uch.

    Dann sagt er aber:
    D:\Projekte\bdOS\source>nasm -f coff -o kernel.o kernel.asm
    kernel.asm:20: COFF format does not support non-32-bit relocations

    D:\Projekte\bdOS\source>nasm -f elf -o kernel.o kernel.asm
    kernel.asm:20: ELF format does not support non-32-bit relocations



  • Irgendwie konnte man eine .obj datei daraus erstellen ich glaub mit -f obj
    die sollte er schon erkennen 😉

    MFG

    LordHoto

    PS: Ist etwas umst]ndlich hier mit links zu schreiben 😉



  • Also ich hab hier meine 2 Dateien, bootloader.asm und kernel.asm
    bootloader.asm

    org 0x7C00 
    
    ; BL starten 
    jmp start 
    
    ; ----- 
    ; Daten 
    ; ----- 
    iBootDrive	db 0 
    
    ; -------- 
    ; BL Start 
    ; -------- 
    start:
        ; Stack aufbauen 
        cli 
        mov ax, 0x9000            	; Adresse des Stack speichern 
        mov ss, ax              	; Stackadresse festlegen 
        mov sp, 0               	; Stackpointer auf 0 setzen 
        sti             
    
        ; Bootlaufwerk sichern 
        mov [iBootDrive], dl 
    
        ; Kernel laden 
        call LoadKernel 
    
        ; Shell aufrufen 
        mov ax, 1000h 
        mov es, ax 
        mov ds, ax 
        push ax 
        mov ax, 0 
        push ax 
        retf 
    
    ; -------------------------- 
    ; Unterprogramm - LoadKernel 
    ; -------------------------- 
    LoadKernel:
        ; Reset des Bootlaufwerkes 
        push ds 
        mov ax, 0 
        mov dl, [iBootDrive] 
        int 13h 
        pop ds 
        jc LoadKernel            ; Bei Fehler nochmal probieren 
    
        load:
        mov ax,0x1000 
        mov es,ax 
        mov bx, 0 
        mov ah, 2 
        mov al, 5 
        mov cx, 2 
        mov dx, 0 
        int 13h 
        jc load 
        retn 
    
    ; Auf 512 Byte auffüllen 
    times 512-($-$$)-2 db 0 
    dw 0AA55h
    

    kernel.asm

    mov ax, 1000h 
    mov ds, ax 
    mov es, ax 
    
    jmp start
    
    szInfo db 'Kernel geladen', 0
    
    ; ------------ 
    ; Kernel Start 
    ; ------------ 
    start:
    	mov si, szInfo
    	call _printstring
    
    hang:
    	jmp hang	
    
        ; Reset      
        jmp reset 
    
    ; -------------------- 
    ; Unterprogramm: reset 
    ; -------------------- 
    reset: 
        db 0Eah 
        dw 0000h 
        dw 0FFFFh
    
    ; --------------------------- 
    ; Unterprogramm - PrintString 
    ; --------------------------- 
    _printstring: 
        mov ah, 0eh 
        mov bx, 7h 
        _printstringloop:
            lodsb 
            int 10h 
            cmp al, 0h 
            je _printstringend 
            jmp _printstring 
        _printstringend: 
        ret
    

    Wird so assembliert:

    D:\Projekte\bdOS\source>nasm -f bin -o bootloader.bin bootloader.asm
    D:\Projekte\bdOS\source>nasm -f bin -o kernel.bin kernel.asm
    

    Dann och zu einem Image gemacht und mit RawWrite auf Diskette geschrieben.
    Funktioniert einwandfrei, d.h. "Kernel geladen" wird angezeigt, dann häng der PC in der Schleife...

    Jetzt würd ich aber gerne aus meiner kernel.asm eine C-Funktion aufrufen, die da wäre:

    void kmain(void)
    {
    	for(;;){}
    }
    

    Sprich, die C-Funktion ersetzt mein

    hang:
      jmp hang
    

    Wie mach ich das jetzt. Probier schon das ganze Wochenende und bin anscheinend zu dumm dazu.

    Könnte mir nicht irgentjemand erklären mit welchen Programmen ich was wie assemblier kompilier und linke, damit das nachher funktioniert???

    Wäre echt cool 😉

    Danke!
    🙂 🙂



  • Mmmmh, kann mir denn wirklich niemand helfen?!
    Ich möchte ganz einfach zu meiner C-Funktion springen und dort Code ausführen! Es kann doch nicht sein, dass es niemand weiss! 😞 😞

    PS: Alles im RealMode...

    BITTE HELFT MIR!!
    Danke!



  • Tjo, mit dem GCC kenne ich mich nicht aus.
    So beim einfachen Rumprobieren habe ich es zumindest nicht hinbekommen, das Teil einfache 16Bit binaries ausspucken zu lassen... Und das wird's wohl sein, was du erstmal brauchst, um dein C-Kernel vernuenftig starten zu koennen... 🙄



  • Nobuo T schrieb:

    Tjo, mit dem GCC kenne ich mich nicht aus.
    So beim einfachen Rumprobieren habe ich es zumindest nicht hinbekommen, das Teil einfache 16Bit binaries ausspucken zu lassen... Und das wird's wohl sein, was du erstmal brauchst, um dein C-Kernel vernuenftig starten zu koennen... 🙄

    Ahh, könnte es dann mit dem tc++ gehen??



  • Vielleicht, wenn er DOS .com-Dateien erstellen kann. Die sind zunaechst 16Bit und haben einen festgelegten Code-entry-point (Offset 100h) und keinen Header oder sonstiges stoerendes Zeug. Nachteil ist, dass die Dinger nicht groesser als 64kB sein koennen.
    Hoffe das hilft dir irgendwie weiter.
    (Wundert mich eigentlich auch ein wenig, dass hier keiner weiter etwas zu schreibt... Ich habe jedenfalls keine Zeit/Lust, mir vor dem Wochenende irgendwelche C-Compiler auszugraben und daran rumzuspielen o.ae. 😉 )



  • mmmh, okay, danke erstmal, meld mich dann halt nochmal

    ciao
    😃


Anmelden zum Antworten