add vorgabe09
This commit is contained in:
@ -84,28 +84,6 @@ inline void PCSPK::delay(int time) {
|
|||||||
|
|
||||||
/* Hier muess Code eingefuegt werden */
|
/* Hier muess Code eingefuegt werden */
|
||||||
|
|
||||||
// 1.19 MHz => 1s for full countdown
|
|
||||||
unsigned short cntStart = 1193180 / 1000; // 1s / 1000 = 1ms countdown
|
|
||||||
|
|
||||||
// 00110000 => 0x30: Counter0, LoByte/HiByte, Mode0, Binary
|
|
||||||
// 00110010 => 0x32: Counter0, LoByte/HiByte, Mode1, Binary
|
|
||||||
// 00110100 => 0x34: Counter0, LoByte/HiByte, Mode2, Binary
|
|
||||||
// 00110110 => 0x36: Counter0, LoByte/HiByte, Mode3, Binary
|
|
||||||
control.outb(0x34); // Zaehler-0 konfigurieren
|
|
||||||
data0.outb(cntStart & 0xFF); // Zaehler-0 laden (Lobyte)
|
|
||||||
data0.outb(cntStart >> 8); // Zaehler-0 laden (Hibyte)
|
|
||||||
|
|
||||||
int initial_count, current_count;
|
|
||||||
for (int i = 0; i < time; ++i) {
|
|
||||||
initial_count = readCounter();
|
|
||||||
while (1) {
|
|
||||||
current_count = readCounter();
|
|
||||||
|
|
||||||
if (current_count > initial_count) break; // The counter has already been reset
|
|
||||||
|
|
||||||
initial_count = current_count;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
|
|||||||
68
c_os/devices/PIT.cc
Executable file
68
c_os/devices/PIT.cc
Executable file
@ -0,0 +1,68 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* *
|
||||||
|
* P I T *
|
||||||
|
* *
|
||||||
|
*---------------------------------------------------------------------------*
|
||||||
|
* Beschreibung: Programmable Interval Timer. *
|
||||||
|
* *
|
||||||
|
* Autor: Michael Schoettner, 3.7.2022 *
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include "devices/PIT.h"
|
||||||
|
#include "kernel/IOport.h"
|
||||||
|
#include "kernel/Globals.h"
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
* Methode: PIT::interval *
|
||||||
|
*---------------------------------------------------------------------------*
|
||||||
|
* Beschreibung: Zeitinervall programmieren. *
|
||||||
|
* *
|
||||||
|
* Parameter: *
|
||||||
|
* us: Zeitintervall in Mikrosekunden, nachdem periodisch ein *
|
||||||
|
* Interrupt erzeugt werden soll. *
|
||||||
|
*****************************************************************************/
|
||||||
|
void PIT::interval (int us) {
|
||||||
|
|
||||||
|
/* hier muss Code eingefuegt werden */
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
* Methode: PIT::plugin *
|
||||||
|
*---------------------------------------------------------------------------*
|
||||||
|
* Beschreibung: Unterbrechungen fuer den Zeitgeber erlauben. Ab sofort *
|
||||||
|
* wird bei Ablauf des definierten Zeitintervalls die *
|
||||||
|
* Methode 'trigger' aufgerufen. *
|
||||||
|
*****************************************************************************/
|
||||||
|
void PIT::plugin () {
|
||||||
|
|
||||||
|
/* hier muss Code eingefuegt werden */
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
* Methode: PIT::trigger *
|
||||||
|
*---------------------------------------------------------------------------*
|
||||||
|
* Beschreibung: ISR fuer den Zeitgeber. Wird aufgerufen, wenn der *
|
||||||
|
* Zeitgeber eine Unterbrechung ausloest. Anzeige der Uhr *
|
||||||
|
* aktualisieren und Thread wechseln durch Setzen der *
|
||||||
|
* Variable 'forceSwitch', wird in 'int_disp' behandelt. *
|
||||||
|
*****************************************************************************/
|
||||||
|
void PIT::trigger () {
|
||||||
|
|
||||||
|
/* hier muss Code eingefuegt werden */
|
||||||
|
|
||||||
|
// alle 10ms, Systemzeit weitersetzen
|
||||||
|
systime++;
|
||||||
|
|
||||||
|
// Bei jedem Tick einen Threadwechsel ausloesen.
|
||||||
|
// Aber nur wenn der Scheduler bereits fertig intialisiert wurde
|
||||||
|
// und ein weiterer Thread rechnen moechte
|
||||||
|
|
||||||
|
/* hier muss Code eingefuegt werden */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
47
c_os/devices/PIT.h
Executable file
47
c_os/devices/PIT.h
Executable file
@ -0,0 +1,47 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* *
|
||||||
|
* P I T *
|
||||||
|
* *
|
||||||
|
*---------------------------------------------------------------------------*
|
||||||
|
* Beschreibung: Programmable Interval Timer. *
|
||||||
|
* *
|
||||||
|
* Autor: Michael Schoettner, 23.8.2016 *
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __PIT_include__
|
||||||
|
#define __PIT_include__
|
||||||
|
|
||||||
|
#include "kernel/interrupts/ISR.h"
|
||||||
|
|
||||||
|
class PIT : public ISR {
|
||||||
|
|
||||||
|
private:
|
||||||
|
PIT(const PIT ©); // Verhindere Kopieren
|
||||||
|
|
||||||
|
private:
|
||||||
|
enum { time_base = 838 }; /* ns */
|
||||||
|
int timer_interval;
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Zeitgeber initialisieren.
|
||||||
|
PIT (int us) {
|
||||||
|
interval (us);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Konfiguriertes Zeitintervall auslesen.
|
||||||
|
int interval () {
|
||||||
|
return timer_interval;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Zeitintervall in Mikrosekunden, nachdem periodisch ein Interrupt
|
||||||
|
//erzeugt werden soll.
|
||||||
|
void interval (int us);
|
||||||
|
|
||||||
|
// Aktivierung der Unterbrechungen fuer den Zeitgeber
|
||||||
|
void plugin ();
|
||||||
|
|
||||||
|
// Unterbrechnungsroutine des Zeitgebers.
|
||||||
|
void trigger ();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -17,9 +17,11 @@ Keyboard kb; // Tastatur
|
|||||||
IntDispatcher intdis; // Unterbrechungsverteilung
|
IntDispatcher intdis; // Unterbrechungsverteilung
|
||||||
PIC pic; // Interrupt-Controller
|
PIC pic; // Interrupt-Controller
|
||||||
unsigned int total_mem; // RAM total
|
unsigned int total_mem; // RAM total
|
||||||
|
unsigned long systime = 0;
|
||||||
// BumpAllocator allocator;
|
// BumpAllocator allocator;
|
||||||
// LinkedListAllocator allocator;
|
// LinkedListAllocator allocator;
|
||||||
TreeAllocator allocator;
|
TreeAllocator allocator;
|
||||||
Scheduler scheduler;
|
Scheduler scheduler;
|
||||||
BIOS bios; // Schnittstelle zum 16-Bit BIOS
|
BIOS bios; // Schnittstelle zum 16-Bit BIOS
|
||||||
VESA vesa; // VESA-Treiber
|
VESA vesa; // VESA-Treiber
|
||||||
|
PIT pit(10000);
|
||||||
|
|||||||
@ -22,6 +22,7 @@
|
|||||||
#include "kernel/interrupts/IntDispatcher.h"
|
#include "kernel/interrupts/IntDispatcher.h"
|
||||||
#include "kernel/interrupts/PIC.h"
|
#include "kernel/interrupts/PIC.h"
|
||||||
#include "kernel/threads/Scheduler.h"
|
#include "kernel/threads/Scheduler.h"
|
||||||
|
#include "devices/PIT.h"
|
||||||
|
|
||||||
extern CPU cpu; // CPU-spezifische Funktionen
|
extern CPU cpu; // CPU-spezifische Funktionen
|
||||||
extern PCSPK pcspk; // PC-Lautsprecher
|
extern PCSPK pcspk; // PC-Lautsprecher
|
||||||
@ -29,7 +30,9 @@ extern CGA_Stream kout; // Ausgabe-Strom fuer Kernel
|
|||||||
extern Keyboard kb; // Tastatur
|
extern Keyboard kb; // Tastatur
|
||||||
extern IntDispatcher intdis; // Unterbrechungsverteilung
|
extern IntDispatcher intdis; // Unterbrechungsverteilung
|
||||||
extern PIC pic; // Interrupt-Controller
|
extern PIC pic; // Interrupt-Controller
|
||||||
|
extern PIT pit; // Zeitgeber
|
||||||
extern unsigned int total_mem; // RAM total
|
extern unsigned int total_mem; // RAM total
|
||||||
|
extern unsigned long systime; // wird all 10ms hochgezaehlt
|
||||||
// extern BumpAllocator allocator;
|
// extern BumpAllocator allocator;
|
||||||
// extern LinkedListAllocator allocator;
|
// extern LinkedListAllocator allocator;
|
||||||
extern TreeAllocator allocator;
|
extern TreeAllocator allocator;
|
||||||
|
|||||||
@ -22,6 +22,9 @@ public:
|
|||||||
IdleThread() {}
|
IdleThread() {}
|
||||||
|
|
||||||
void run() override {
|
void run() override {
|
||||||
|
// Idle-Thread läuft, ab jetzt ist der Scheduler fertig initialisiert
|
||||||
|
scheduler.setInitialized();
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
scheduler.yield();
|
scheduler.yield();
|
||||||
// kout << "Idle!" << endl;
|
// kout << "Idle!" << endl;
|
||||||
|
|||||||
@ -22,7 +22,8 @@ void Scheduler::schedule() {
|
|||||||
/* hier muss Code eingefuegt werden */
|
/* hier muss Code eingefuegt werden */
|
||||||
|
|
||||||
Thread* idle = new IdleThread();
|
Thread* idle = new IdleThread();
|
||||||
this->readyQueue.enqueue(idle);
|
// this->readyQueue.enqueue(idle);
|
||||||
|
this->ready(idle);
|
||||||
|
|
||||||
/* Bevor diese Methode anufgerufen wird, muss zumindest der Idle-Thread
|
/* Bevor diese Methode anufgerufen wird, muss zumindest der Idle-Thread
|
||||||
* in der Queue eingefuegt worden sein.
|
* in der Queue eingefuegt worden sein.
|
||||||
@ -44,7 +45,13 @@ void Scheduler::ready(Thread* that) {
|
|||||||
|
|
||||||
/* hier muss Code eingefuegt werden */
|
/* hier muss Code eingefuegt werden */
|
||||||
|
|
||||||
|
// Thread-Wechsel durch PIT verhindern
|
||||||
|
cpu.disable_int ();
|
||||||
|
|
||||||
this->readyQueue.enqueue(that);
|
this->readyQueue.enqueue(that);
|
||||||
|
|
||||||
|
// Thread-Wechsel durch PIT jetzt wieder erlauben
|
||||||
|
cpu.enable_int ();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
@ -59,8 +66,14 @@ void Scheduler::exit() {
|
|||||||
|
|
||||||
/* hier muss Code eingefuegt werden */
|
/* hier muss Code eingefuegt werden */
|
||||||
|
|
||||||
|
// Thread-Wechsel durch PIT verhindern
|
||||||
|
cpu.disable_int ();
|
||||||
|
|
||||||
Thread& next = *(Thread*)this->readyQueue.dequeue();
|
Thread& next = *(Thread*)this->readyQueue.dequeue();
|
||||||
this->dispatch(next);
|
this->dispatch(next);
|
||||||
|
|
||||||
|
// Interrupts werden in Thread_switch in Thread.asm wieder zugelassen
|
||||||
|
// dispatch kehr nicht zurueck
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
@ -78,7 +91,13 @@ void Scheduler::kill(Thread* that) {
|
|||||||
|
|
||||||
/* hier muss Code eingefuegt werden */
|
/* hier muss Code eingefuegt werden */
|
||||||
|
|
||||||
|
// Thread-Wechsel durch PIT verhindern
|
||||||
|
cpu.disable_int ();
|
||||||
|
|
||||||
this->readyQueue.remove(that);
|
this->readyQueue.remove(that);
|
||||||
|
|
||||||
|
// Thread-Wechsel durch PIT jetzt wieder erlauben
|
||||||
|
cpu.enable_int ();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
@ -96,6 +115,9 @@ void Scheduler::yield() {
|
|||||||
|
|
||||||
/* hier muss Code eingefuegt werden */
|
/* hier muss Code eingefuegt werden */
|
||||||
|
|
||||||
|
// Thread-Wechsel durch PIT verhindern
|
||||||
|
cpu.disable_int ();
|
||||||
|
|
||||||
// When only one thread exists (IdleThread) it can't yield as the readyqueue becomes empty
|
// When only one thread exists (IdleThread) it can't yield as the readyqueue becomes empty
|
||||||
// and this is not handled anywhere else
|
// and this is not handled anywhere else
|
||||||
if (this->readyQueue.isEmpty()) {
|
if (this->readyQueue.isEmpty()) {
|
||||||
@ -106,4 +128,20 @@ void Scheduler::yield() {
|
|||||||
Thread& next = *(Thread*)this->readyQueue.dequeue();
|
Thread& next = *(Thread*)this->readyQueue.dequeue();
|
||||||
this->readyQueue.enqueue(this->get_active());
|
this->readyQueue.enqueue(this->get_active());
|
||||||
this->dispatch(next);
|
this->dispatch(next);
|
||||||
|
|
||||||
|
// Thread-Wechsel durch PIT jetzt wieder erlauben
|
||||||
|
cpu.enable_int ();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
* Methode: Scheduler::preempt *
|
||||||
|
*---------------------------------------------------------------------------*
|
||||||
|
* Beschreibung: Diese Funktion wird aus der ISR des PITs aufgerufen und *
|
||||||
|
* schaltet auf den naechsten Thread um, sofern einer vor- *
|
||||||
|
* handen ist. *
|
||||||
|
*****************************************************************************/
|
||||||
|
void Scheduler::preempt () {
|
||||||
|
|
||||||
|
/* Hier muss Code eingefuegt werden */
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -22,8 +22,20 @@ private:
|
|||||||
|
|
||||||
Queue readyQueue; // auf die CPU wartende Threads
|
Queue readyQueue; // auf die CPU wartende Threads
|
||||||
|
|
||||||
|
// Scheduler wird evt. von einer Unterbrechung vom Zeitgeber gerufen,
|
||||||
|
// bevor er initialisiert wurde
|
||||||
|
bool initialized;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Scheduler() {}
|
Scheduler() : initialized(false) {}
|
||||||
|
|
||||||
|
// Scheduler initialisiert?
|
||||||
|
// Zeitgeber-Unterbrechung kommt evt. bevor der Scheduler fertig
|
||||||
|
// intiialisiert wurde!
|
||||||
|
bool isInitialized() { return initialized; }
|
||||||
|
|
||||||
|
// ruft nur der Idle-Thread (erster Thread der vom Scheduler gestartet wird)
|
||||||
|
void setInitialized() { initialized = true; }
|
||||||
|
|
||||||
// Scheduler starten
|
// Scheduler starten
|
||||||
void schedule();
|
void schedule();
|
||||||
@ -39,6 +51,10 @@ public:
|
|||||||
|
|
||||||
// CPU freiwillig abgeben und Auswahl des naechsten Threads
|
// CPU freiwillig abgeben und Auswahl des naechsten Threads
|
||||||
void yield();
|
void yield();
|
||||||
|
|
||||||
|
|
||||||
|
// Thread umschalten; wird aus der ISR des PITs gerufen
|
||||||
|
void preempt ();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -70,6 +70,15 @@ void Thread_init(struct ThreadState* regs, unsigned int* stack, void (*kickoff)(
|
|||||||
regs->edi = 0;
|
regs->edi = 0;
|
||||||
regs->ebp = 0;
|
regs->ebp = 0;
|
||||||
regs->esp = sp; // esp now points to the location of the address of kickoff
|
regs->esp = sp; // esp now points to the location of the address of kickoff
|
||||||
|
|
||||||
|
// nachfolgend die fluechtige Register
|
||||||
|
// wichtig fuer preemptives Multitasking
|
||||||
|
regs->eax = 0;
|
||||||
|
regs->ecx = 0;
|
||||||
|
regs->edx = 0;
|
||||||
|
|
||||||
|
// flags initialisieren
|
||||||
|
regs->efl = (void*)0x200; // Interrupt-Enable
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
|
|||||||
@ -15,6 +15,13 @@
|
|||||||
* ThreadState, in dem die Werte der nicht-fluechtigen *
|
* ThreadState, in dem die Werte der nicht-fluechtigen *
|
||||||
* Register gesichert werden koennen. *
|
* Register gesichert werden koennen. *
|
||||||
* *
|
* *
|
||||||
|
* Zusaetzlich zum vorhandenen freiwilligen Umschalten der *
|
||||||
|
* CPU mit 'Thread_switch' gibt es nun ein forciertes Um- *
|
||||||
|
* durch den Zeitgeber-Interrupt ausgeloest wird und in *
|
||||||
|
* Assembler in startup.asm implementiert ist. Fuer das *
|
||||||
|
* Zusammenspiel mit dem Scheduler ist die Methode *
|
||||||
|
* 'prepare_preemption' in Scheduler.cc wichtig. *
|
||||||
|
* *
|
||||||
* Autor: Michael, Schoettner, HHU, 16.12.2016 *
|
* Autor: Michael, Schoettner, HHU, 16.12.2016 *
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|||||||
@ -24,3 +24,7 @@ esi_offset: resd 1
|
|||||||
edi_offset: resd 1
|
edi_offset: resd 1
|
||||||
ebp_offset: resd 1
|
ebp_offset: resd 1
|
||||||
esp_offset: resd 1
|
esp_offset: resd 1
|
||||||
|
eax_offset: resd 1
|
||||||
|
ecx_offset: resd 1
|
||||||
|
edx_offset: resd 1
|
||||||
|
efl_offset: resd 1
|
||||||
|
|||||||
@ -34,6 +34,12 @@ struct ThreadState {
|
|||||||
void* edi;
|
void* edi;
|
||||||
void* ebp;
|
void* ebp;
|
||||||
void* esp;
|
void* esp;
|
||||||
|
// nachfolgend die fluechtige Register
|
||||||
|
// wichtig fuer preemptives Multitasking
|
||||||
|
void *eax;
|
||||||
|
void *ecx;
|
||||||
|
void *edx;
|
||||||
|
void *efl;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -8,10 +8,18 @@
|
|||||||
;* Es wird alles vorbereitet, damit so schnell wie moeglich *
|
;* Es wird alles vorbereitet, damit so schnell wie moeglich *
|
||||||
;* die weitere Ausfuehrung durch C-Code erfolgen kann. *
|
;* die weitere Ausfuehrung durch C-Code erfolgen kann. *
|
||||||
;* *
|
;* *
|
||||||
|
;* Hier erweitert, um BIOS callund Paging-Aktivierung, *
|
||||||
|
;* Unterstuetzung des Bluescreens und preemptives *
|
||||||
|
;* Thread-Switching. *
|
||||||
|
;* *
|
||||||
;* Autor: Olaf Spinczyk, TU Dortmund *
|
;* Autor: Olaf Spinczyk, TU Dortmund *
|
||||||
;* Michael Schoettner, HHU, 15.12.2018 *
|
;* Michael Schoettner, HHU, 3.7.2022 *
|
||||||
;******************************************************************************
|
;******************************************************************************
|
||||||
|
|
||||||
|
; fuer preemptives Umschalten zwischen Threads
|
||||||
|
%include "kernel/threads/Thread.inc"
|
||||||
|
|
||||||
|
|
||||||
; Multiboot-Konstanten
|
; Multiboot-Konstanten
|
||||||
MULTIBOOT_PAGE_ALIGN equ 1<<0
|
MULTIBOOT_PAGE_ALIGN equ 1<<0
|
||||||
MULTIBOOT_MEMORY_INFO equ 1<<1
|
MULTIBOOT_MEMORY_INFO equ 1<<1
|
||||||
@ -36,6 +44,7 @@ MULTIBOOT_EAX_MAGIC equ 0x2badb002
|
|||||||
[GLOBAL get_page_fault_address]
|
[GLOBAL get_page_fault_address]
|
||||||
[GLOBAL get_int_esp]
|
[GLOBAL get_int_esp]
|
||||||
|
|
||||||
|
|
||||||
; Michael Schoettner:
|
; Michael Schoettner:
|
||||||
; Nachfolgender label steht fuer das 'delete', welches jetzt implementiert
|
; Nachfolgender label steht fuer das 'delete', welches jetzt implementiert
|
||||||
; wird. Damit der Linker nicht wegen doppelter Definition "meckert"
|
; wird. Damit der Linker nicht wegen doppelter Definition "meckert"
|
||||||
@ -158,17 +167,17 @@ wrapper i
|
|||||||
|
|
||||||
; Gemeinsamer Rumpf
|
; Gemeinsamer Rumpf
|
||||||
wrapper_body:
|
wrapper_body:
|
||||||
cld ; das erwartet der gcc so.
|
cld ; das erwartet der gcc so.
|
||||||
push ecx ; Sichern der fluechtigen Register
|
push ecx ; Sichern der fluechtigen Register
|
||||||
push edx
|
push edx
|
||||||
and eax,0xff ; Der generierte Wrapper liefert nur 8 Bits
|
and eax,0xff ; Der generierte Wrapper liefert nur 8 Bits
|
||||||
push eax ; Nummer der Unterbrechung uebergeben
|
push eax ; Nummer der Unterbrechung uebergeben
|
||||||
call int_disp
|
call int_disp; Interrupt-Dispatcher aufrufen
|
||||||
add esp,4 ; Parameter vom Stack entfernen
|
add esp,4 ; Parameter vom Stack entfernen
|
||||||
pop edx ; fluechtige Register wieder herstellen
|
pop edx ; fluechtige Register wieder herstellen
|
||||||
pop ecx
|
pop ecx
|
||||||
popad ; alle Register wiederherstellen
|
popad ; alle Register wiederherstellen
|
||||||
iret ; fertig!
|
iret ; fertig!
|
||||||
|
|
||||||
;
|
;
|
||||||
; setup_idt
|
; setup_idt
|
||||||
@ -371,7 +380,7 @@ idt16_descr:
|
|||||||
; (genauerer Stack-Aufbau siehe Bluescreen.cc)
|
; (genauerer Stack-Aufbau siehe Bluescreen.cc)
|
||||||
;
|
;
|
||||||
; |-------------|
|
; |-------------|
|
||||||
; | EFLAGS |
|
; | EFLAGS |
|
||||||
; |-------------|
|
; |-------------|
|
||||||
; | CS |
|
; | CS |
|
||||||
; |-------------|
|
; |-------------|
|
||||||
@ -379,8 +388,9 @@ idt16_descr:
|
|||||||
; |-------------|
|
; |-------------|
|
||||||
; | [ErrorCode] |
|
; | [ErrorCode] |
|
||||||
; |-------------|
|
; |-------------|
|
||||||
; | alle Regs. |
|
; | alle Regs. |
|
||||||
; | (PUSHAD) |
|
; | (PUSHAD) |
|
||||||
; |-------------| <-- int_esp
|
; |-------------| <-- int_esp
|
||||||
int_esp:
|
int_esp:
|
||||||
db 0,0,0,0
|
db 0,0,0,0
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user