Autor Thema: Verständnisfragen  (Gelesen 16936 mal)

ChristianF

  • Beiträge: 296
    • Profil anzeigen
    • DeutschOS - Betriebssystem Projekt
Gespeichert
« Antwort #20 am: 15. October 2009, 12:05 »
Da war ich wohl wieder falsch. Schon blöd bei popa zu schauen, wenn man pusha haben will...
 
Gepusht wird es auf jeden fall, laut manual. Nur wird es nicht wieder zurückgesetzt. Das Zurücksetzen übernimmt dann der/das Mnemonic "iret".  :-D

XanClic

  • Beiträge: 261
    • Profil anzeigen
    • github
Gespeichert
« Antwort #21 am: 15. October 2009, 18:36 »
Ein Tipp:
; Macro for isr stub without an already pushed error code
%macro INT_STUB 1
global intr_stub%1
intr_stub%1:
cli
push byte %1 ; ISR-Number
push byte 0 ; Dummy error code for a uniform stack frame
jmp interrupt_handler_stub
%endmacro
Ich würde das Pushen von Pseudofehlercode und Interruptnummer vertauschen, da ja im Falle eines Fehlercodes zuerst der Fehlercode auf dem Stack liegt und dann die Nummer des Interrupts hinterher gepusht wird. :-)
« Letzte Änderung: 15. October 2009, 18:38 von XanClic »

ChristianF

  • Beiträge: 296
    • Profil anzeigen
    • DeutschOS - Betriebssystem Projekt
Gespeichert
« Antwort #22 am: 15. October 2009, 23:07 »
Nun, anscheinend war das einer der Fehler, die nun gelöst sind...  :roll:
 
Ich habe in den Makros nun anstatt "push byte %1" nur noch "push %1" stehen, da das byte ja Vorzeichenbehaftet ist, somit bei "int 0x80" immer -128 herauskommt.
Was macht das ganze für einen Unterschied? Nutzt nasm dann den Typ, der gerade passt oder wie sieht das aus?

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #23 am: 16. October 2009, 00:04 »
Bei push byte oder word wird immer sign extended. Darauf hast du keinen Einfluss. Wenn du das nicht willst, musst du push dword nehmen. NASM hat da also auch keine Wahl, außer deinen Befehl zu befolgen und den Wert als vorzeichenbehaftetes byte und somit -128 auf den Stack zu legen.

Wenn du das Vorzeichen in der weiteren Behandlung in C ignorieren willst, könntest du den Parameter als unsigned char deklarieren. Dann solltest du wieder den Wert +128 bekommen.
Dieser Text wird unter jedem Beitrag angezeigt.

ChristianF

  • Beiträge: 296
    • Profil anzeigen
    • DeutschOS - Betriebssystem Projekt
Gespeichert
« Antwort #24 am: 16. October 2009, 09:07 »
Nun ja...
Die Werte (ISR Nummer und Error Code) sind in einer Struktur als unsigned int abgelegt... Ich müsste ja dann eigentlich auch push dword benutzen oder?

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #25 am: 16. October 2009, 20:43 »
ja, das wäre vermutlich das einfachste.
Dieser Text wird unter jedem Beitrag angezeigt.

ChristianF

  • Beiträge: 296
    • Profil anzeigen
    • DeutschOS - Betriebssystem Projekt
Gespeichert
« Antwort #26 am: 10. November 2009, 08:52 »
Es gibt mal wieder etwas unklares...  :roll:
 
Da ich vor kurzem mein System gründlich sabotiert habe und nicht mehr auf meine Daten zugreifen konnte, musste, bzw. muss, ich einige Teile von meinem Betriebssystem nochmals schreiben. Hier bin ich bei folgendem Stück Code hängen geblieben:
; Push created stack
mov eax, esp
push eax
; Call C-Function
mov eax, interrupts_handler
call eax
pop eax

Wenn man auf normalem Wege eine C-Funktion in Assembler aufruft (call my_cfunction), so muss man nach dem call esp um 4 erhöhen, damit der Rest danach noch ausgeführt wird.
Bei obiger Implementation, die ich aus einem Tutorial entnommen habe ist das nicht nötig, aber warum? Was passiert genau, wenn der Wert in eax per "call"-instruction aufgerufen wird?

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #27 am: 10. November 2009, 09:35 »
Wie du ja vermutlich weißt, werden die Parameter einer Funktion in der C-Aufrufkonvention (auf i386) auf dem Stack übergeben. Dabei ist der Aufrufer sowohl dafür verantwortlich, die Parameter auf den Stack zu legen (das ist offensichtlich) als auch dafür, die Parameter hinterher wieder runterzunehmen. Das kann man entweder mit einem pop machen, wie das dein Beispielcode hier tut, oder wenn man den Wert nicht mehr braucht, kann man einfach den Stackpointer erhöhen, also die add-Variante.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

ChristianF

  • Beiträge: 296
    • Profil anzeigen
    • DeutschOS - Betriebssystem Projekt
Gespeichert
« Antwort #28 am: 10. November 2009, 13:00 »
Das mit den Aufrufkonventionen wußte ich, aber warum nur i386? Ist das bei einer 64Bit CPU anders?
 
Noch etwas, da ich ja grad bei Interrupts bin. Wenn ich den PIC nehme, mappe ich die IRQs von 32 bis 48. Das ist aber nur der PIC, wie sieht das mit dem local APIC aus? Da sind das ja mehr als nur die 16 IRQs. Muss ich da extra einen speziellen handler für den APIC-Krempel schreiben?
 
Btw. Ich habe mich noch nicht viel mit dem APIC beschäftigt, nur auslesen, ob dieser überhaupt vorhanden ist, und wo die Basisregister im Speicher anfangen...

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #29 am: 10. November 2009, 13:44 »
Das mit den Aufrufkonventionen wußte ich, aber warum nur i386? Ist das bei einer 64Bit CPU anders?
Ja, auf amd64 werden erstmal Register hergenommen bevor der Stack drankommt.
 
Die APIC-Frage überlasse ich mal jemandem, der das schon implementiert hat.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

ChristianF

  • Beiträge: 296
    • Profil anzeigen
    • DeutschOS - Betriebssystem Projekt
Gespeichert
« Antwort #30 am: 11. November 2009, 17:33 »
Ich habe mal in den Code von lightOS rein geschaut...
Hier hatte die Klasse für den PIC, sowie APIC eine Methode "handle_irq". Daraus habe ich geschlossen, dass das getrennt behandelt werden muss. Da ich aber keine Lust habe jedes mal bei einem IRQ zu prüfen, ob denn ein APIC oder ein PIC vorhanden ist, habe ich einen globalen Funktionszeiger angelegt, der dann eben immer aufgerufen wird.
In den entsprechenden Funktionen muss man dann eben prüfen, ob es sich bei dem Interrupt überhaupt um einen IRQ handelt, da PIC und APIC anscheinend zu verschieden sind, als dass ich das mit einem If erledigen könnte:
//...
void (*hardware_interrupt_handler)(registers_t*) = 0;
//...void interrupts_handler(registers_t *r)
{
// An error occured
if(r->interrupt_number < 32)
{
video_puts(exception_messages[r->interrupt_number]);
video_puts(" Exception. System Halted!\n");
for(;;);
}

if(r->interrupt_number == 0x80)
{
// handle system call
}

// handle hardware interrupts
if(hardware_interrupt_handler != 0)
hardware_interrupt_handler(r);
}

Ist eben die Frage, was besser ist... die Lösung oben oder die, in der mit einer boolschen Variable geprüft und die entsprechende Funktion aufgerufen wird...

ChristianF

  • Beiträge: 296
    • Profil anzeigen
    • DeutschOS - Betriebssystem Projekt
Gespeichert
« Antwort #31 am: 13. November 2009, 13:15 »
Doppel-Posts sind böse, aber beim Editieren besteht die Möglichkeit, dass das niemand liest...
 
Ich habe mich etwas weiter eingelesen in den Local APIC. Nun heißt es, dass bei einem System mit nur einem Prozessor kein I/O APIC vorhanden ist, weshalb der PIC für Hardware Interrupts genutzt wird. Muss ich also nach der Initialisierung des local APIC den PIC zusätzlich initialisieren, oder übernimmt das der local APIC während der Initialisierung?

sebi2020

  • Beiträge: 130
    • Profil anzeigen
    • Infortus OS
Gespeichert
« Antwort #32 am: 16. November 2009, 18:53 »
Ich will ja keinem dazwischenpfuschen oder so, aber ich hab da noch mal ne Frage zum ersten Beitrag am Anfang. dieses align, was bewirkt dass, ich habs nicht ganz verstanden. im multiboot header, wird align 4 verwendet, und was genau verändert dieses macro?
das hab ich nicht so ganz verstanden. sry ;-)
Please press any-key...
Verflucht wo ist any-key? hier? ach Mist, das war Escape...

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #33 am: 16. November 2009, 19:06 »
Es sorgt dafür, dass die nächste Ausgabe auf eine 32-Bit-Grenze ausgerichtet wird, es wird also die Adresse auf die nächsten ganzen vier Bytes aufgerundet. Das ist einfach eine Voraussetzung, die so in der Multibootspezifikation steht.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

ChristianF

  • Beiträge: 296
    • Profil anzeigen
    • DeutschOS - Betriebssystem Projekt
Gespeichert
« Antwort #34 am: 17. November 2009, 08:37 »
Ich will ja keinem dazwischenpfuschen oder so, aber ich hab da noch mal ne Frage zum ersten Beitrag am Anfang. dieses align, was bewirkt dass, ich habs nicht ganz verstanden. im multiboot header, wird align 4 verwendet, und was genau verändert dieses macro?
das hab ich nicht so ganz verstanden. sry ;-)
Dafür ist der Thread doch da. :-D

So bin ich mal wieder ein bisschen schlauer geworden.  :roll:
Ich beschäftige ja mich immer noch mit dem local APIC und hier gibt es "feste Events" (mir fällt kein besserer Begriff ein), wie den APIC Timer, LINT0, LINT1 usw.
Diese werden immer vom installierten I/O APIC ausgelöst. Folglich gibt es immer einen I/O APIC, wenn es einen local APIC gibt. Gibt es keinen local APIC, ist kein I/O APIC da und man muss den normalen PIC nehmen.
 
Sollte sich jemand bereits etwas mehr damit beschäftigt haben (local APIC, I/O APIC), und ich habe was falsches geschrieben, dann korrigiert mich bitte...  :-)

sebi2020

  • Beiträge: 130
    • Profil anzeigen
    • Infortus OS
Gespeichert
« Antwort #35 am: 20. November 2009, 21:17 »
Ich hab mal ne Frage zum Linker. wenn ich mein Linkerscript schreibe, warum muss dann der Linker wissen, wo die Datei am ende in den Speicher geladen wird?
Ich meine wenn ich jetzt nen programm schreibe, und wir davon ausgehen, das dass System ohne Paging arbeit, kann man doch garnicht wissen, wo dass Programm am Ende im Speicher landet, oder? Also beim Linken kann man dass doch garnicht wissen?
Please press any-key...
Verflucht wo ist any-key? hier? ach Mist, das war Escape...

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #36 am: 20. November 2009, 21:31 »
Du musst es aber wissen (außer bei Position Independent Code), denn der Linker muss aus deinen Labels ja konkrete Adressen machen. Wenn du kein Paging hast, willst du im Normalfall wenigstens Segmentierung nehmen, so dass du auch mehrere Programme an derselben virtuellen Adresse laufen lassen kannst.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

sebi2020

  • Beiträge: 130
    • Profil anzeigen
    • Infortus OS
Gespeichert
« Antwort #37 am: 20. November 2009, 21:48 »
wie soll das gehn (position independent?) ich dachte, dass wäre bei paging kein problem, da jedes programm seinen eigenen virtuellen adressraum hat. dass muss ich wissen? Ich kann mir nicht vorstellen  dass jeder Programmierer sich dann noch Gedanken macht, wo dass OS das Programm hinladen könnte, woher soll er das auch wissen?! ... und ich meine wo ist dann der unterschied ob ich in einer asm datei "org 0x7c00"
oder im linkerscript ". = 0x7c00" schreibe?
« Letzte Änderung: 20. November 2009, 21:50 von sebi2020 »
Please press any-key...
Verflucht wo ist any-key? hier? ach Mist, das war Escape...

MNemo

  • Beiträge: 547
    • Profil anzeigen
Gespeichert
« Antwort #38 am: 20. November 2009, 22:21 »
wie soll das gehn (position independent?)
Im long mode gibt es die möglichkeit relativ zu RIP zu adressieren(z.B.: mov rax, [rip + 0xf00ba123])

Zitat
ich dachte, dass wäre bei paging kein problem, da jedes programm seinen eigenen virtuellen adressraum hat. dass muss ich wissen? Ich kann mir nicht vorstellen  dass jeder Programmierer sich dann noch Gedanken macht, wo dass OS das Programm hinladen könnte, woher soll er das auch wissen?!
Für gewöhnlich ist das eine feste(bekannte) Adresse. MS-DOS lädt .COM Dateien z.B. immer nach 0x100.

Zitat
... und ich meine wo ist dann der unterschied ob ich in einer asm datei "org 0x7c00"
oder im linkerscript ". = 0x7c00" schreibe?
es gibt keinen
« Letzte Änderung: 20. November 2009, 22:52 von MNemo »
„Wichtig ist nicht, besser zu sein als alle anderen. Wichtig ist, besser zu sein als du gestern warst!“

sebi2020

  • Beiträge: 130
    • Profil anzeigen
    • Infortus OS
Gespeichert
« Antwort #39 am: 20. November 2009, 22:27 »
ist long mode nicht ein modus von 64 bit prozessoren?
Please press any-key...
Verflucht wo ist any-key? hier? ach Mist, das war Escape...

 

Einloggen