Autor Thema: Registerübergabe von ASM an C  (Gelesen 2649 mal)

Hobby Programmiere

  • Beiträge: 42
    • Profil anzeigen
Gespeichert
« am: 14. November 2009, 16:32 »
Hi Leute,
ich habe jetzt schon seit langer Zeit Probleme mit der Registerübergabe. Ich möchte, dass wenn ein ISR-Handler aufgerufen wird, alle Register der CPU an die C-Funktion übergeben werden. Da bei vielen Tuts auch gleich so ein Beispiel war, wollte ich jetzt einfach mal das hier ausprobieren http://www.osdever.net/bkerndev/Docs/isrs.htm
Aber es funktioniert nicht. Der ISR-handler wird zwar aufgerufen, aber als Description kommen nur 3 kryptische Zeichen.
Des weiteren habe ich noch eine Verständnisfrage:
Die CPU_Register sind ja alle unterschiedlich groß. (Es gibt 32bit, 16bit, ...)
Warum werden in allen Tuts die Register in jeweils einen int gepackt? Wenn sie doch unterschiedlich groß sind, müsste man doch auch unterschiedliche Datentypen nehmen.
Hier mein Code:
struct SISRParam
{
    unsigned int gs, fs, es, ds;      /* pushed the segs last */
    unsigned int edi, esi, ebp, esp, ebx, edx, ecx, eax;  /* pushed by 'pusha' */
    unsigned int int_no, err_code;    /* our 'push byte #' and ecodes do this */
    unsigned int eip, cs, eflags, useresp, ss;   /* pushed by the processor automatically */

};

const char* ExceptionMessage[] = // Descriptions for the Exceptions
{
    "Division By Zero Exception",
    "Debug Exception",
    "Non Maskable Interrupt Exception",
    "Breakpoint Exception",
    "Into Detected Overflow Exception",
    "Out of Bounds Exception",
    "Invalid Opcode Exception",
    "No Coprocessor Exception",
    "Double Fault Exception",
    "Coprocessor Segment Overrun Exception",
    "Bad TSS Exception",
    "Segment Not Present Exception",
    "Stack Fault Exception",
    "General Protection Fault Exception",
    "Page Fault Exception",
    "Unknown Interrupt Exception",
    "Coprocessor Fault Exception",
    "Alignment Check Exception",
    "Machine Check Exception",
    "Reserved Exceptions",
    "Reserved Exceptions",
    "Reserved Exceptions",
    "Reserved Exceptions",
    "Reserved Exceptions",
    "Reserved Exceptions",
    "Reserved Exceptions",
    "Reserved Exceptions",
    "Reserved Exceptions",
    "Reserved Exceptions",
    "Reserved Exceptions",
    "Reserved Exceptions"
};
ISR0:
    cli                     ; Disable all interrupts
    push byte 0             ; Push the isr number on th stack
    push byte 0
    jmp FAULT_HANDLER     ; Jump to the general faulthandler

ISR1:
    cli
    push byte 1
    push byte 1
    jmp FAULT_HANDLER


    ; Create the parameters
    pusha
    push ds
    push es
    push fs
    push gs
    mov ax, 0x10   ; Load the Kernel Data Segment descriptor!
    mov ds, ax
    mov es, ax
    mov fs, ax
    mov gs, ax
    mov eax, esp   ; Push us the stack
    push eax
    ; Call the c-FaultHandler
    mov eax, FaultHandler
    call eax
    ret


Was habe ich falsch gemacht?

AcidIO

  • Beiträge: 11
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 15. November 2009, 01:09 »
Zitat
Die CPU_Register sind ja alle unterschiedlich groß. (Es gibt 32bit, 16bit, ...)
Warum werden in allen Tuts die Register in jeweils einen int gepackt? Wenn sie doch unterschiedlich groß sind, müsste man doch auch unterschiedliche Datentypen nehmen.

Das liegt daran, dass die Register auf dem Stack(welchen du als Pointer an die Funktion übergibts) alle 32-Bit groß sind.

Zitat
Aber es funktioniert nicht. Der ISR-handler wird zwar aufgerufen, aber als Description kommen nur 3 kryptische Zeichen.

Hast du daran gedacht, dass dein C-Fault-Handler als Parameter einen Pointer auf SISRParam haben muss, da du ja nur den Stackpointer als Parameter übergibst? Könntest du deinen C-Fault-Handler vlt. mal posten?
Wer nichts wagt kann nichts verlieren...

Hobby Programmiere

  • Beiträge: 42
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 15. November 2009, 11:41 »
Ah, ok. Das mit den Register habe ich nun verstanden.
Hier der Code des FaultHandlers
void FaultHandler(struct SISRParam* Param)
{
    // Print an error on the screen the screen and stop the cpu
    ClsEx(0x47);
    SetTextAttribute(0x47);
    kprintf("Exception", 0, 0);

    // Print an discription on the screen
    kprintf("Description: ", 0, 1);
    if(Param->int_no < 32)
        kprintf((char*) ExceptionMessage[Param->int_no], 13, 1);

    // Show all register
    kprintf("Register:", 0, 2);

    kprintf("GS:", 3, 3);
    kprintf("FS:", 15, 3);
    kprintf("ES:", 27, 3);
    kprintf("DS:", 38, 3);
    kprintf("EAX:", 52, 3);

    kprintf("EDI:", 3, 4);
    kprintf("ESI:", 15, 4);
    kprintf("EBP:", 27, 4);
    kprintf("ESP:", 38, 4);
    kprintf("EBX:", 52, 4);
    kprintf("EDX:", 65, 4);

    kprintf("ECX:", 3, 5);
    kprintf("EIP:", 15, 5);
    kprintf("CS:", 27, 5);
    kprintf("EFLAGS:", 38, 5);
    kprintf("USERSP:", 52, 5);
    kprintf("SS:", 65, 5);

    // Stop the CPU
    kprintf("System halted!", 0, 6);
    SetCursor(0, 7);
    asm volatile ("hlt");
}

Hobby Programmiere

  • Beiträge: 42
    • Profil anzeigen
Gespeichert
« Antwort #3 am: 18. November 2009, 17:26 »
Ich nochmal.
Ich habe in den letzten tagen eine Menge rumexperimentiert. Und habe jetzt, glaube ich, das Problem gefunden. Es schien so, als ob kprintf das Problem ist.
Den kprintf gibt etwas anderes aus, als der code tut, mit dem ich direckt in dem Videoram schreibe.
void kprintf(char* chBuffer, const unsigned int iXPos, const unsigned int iYPos)
{
    // Compute the position in the ram
    char* VGAMem = (char*) 0xB8000;
    VGAMem += (iYPos * 80 + iXPos) * 2;

    // Print every char with the attributes on the screen
    while(*chBuffer)
    {

        *VGAMem = *chBuffer;
        VGAMem++;
        *VGAMem = iAttribute;
        VGAMem++;
        chBuffer++;
    }
}
Eine Idee, was daran falsch sein könnte? Vielleicht liegt es am Zeiger...

 

Einloggen