Vielen Dank für die Antwort.
Es waren die Segmente. Ich hatte sie nicht auf Realmode eingestellt.
Doch nun eröffnet sich für mich gleich die nächste Frage.
Um die Interrupts im Virtual86 Task zu handeln, habe ich IOPL auf 0 eingestellt, damit bei int, pushf, popf, iret, cli, sti eine General Protection Exception ausgelöst wird.
Dann schaue ich nach, welcher der genannten Befehle die Exception ausgelöst hat und emuliere diesen.
Z.B. bei "int 10h" speichere ich die Rüchsprungadresse auf dem V86-Stack und hole mir in der Realmode Interruptvektortabelle die Adresse vom Interrupt-Handler.
Um diesen dann auszuführen sieht Intel vor dies durch ein iret zu bewerkstelligen.
Leider funktioniert das bei mir nur in BOCHS. Auf dem echten PC und bei MS Virtual PC löst der iret Befehl für den Rücksprung zum V86 Interrupt-Handler wiederum eine General Protection Exception aus.
Ich poste mal einen Teil meines (teilweise) kommentierten Exceptionhandlers für General Protection Exception:
(CONST_FIRSTMB_SEGMENT beinhaltet einen Selektor, der als pseudo Datensegment auf das erste Megabyte des Arbeitsspeichers zeigt; Physikalische Adresse 0x0 bis 0x100000)
pop ecx ; Error Code
pop ecx ; eip
pop ebx ; cs
push ebx
push ecx
mov ax, CONST_FIRSTMB_SEGMENT
mov es, ax
shl ebx, 4
add ebx, ecx
mov edi, ebx
mov bx, [es:edi]
mov ax, bx
and ax, 00ffh
cmp ax, 00cdh
jne NEAR no_v86_int
shr bx, 8
shl bx, 2
mov di, bx
mov ax, [es:edi] ; ax = offset
mov bx, [es:edi+2] ; bx = segment
mov bp, ax
pop eax ; ip
pop ecx ; cs
pop edx ; FLAG
pop edi ; sp
pop esi ; ss
push bp ; save offset of int handler
push bx ; save segment of int handler
push eax
push ecx
push edx
mov bx, si
mov ax, di
shl bx, 4
add bx, ax
xor edi, edi
mov di, bx
mov ax, CONST_FIRSTMB_SEGMENT
mov es, ax ; es:edi pointer to stack of v86 task
sub edi, 2
pop eax
mov [es:edi], ax ; push FLAG on v86 stack
mov ecx, eax
sub edi, 2
pop eax
mov [es:edi], ax ; push cs on v86 stack
sub edi, 2
pop eax
mov [es:edi], ax ; push ip on v86 stack
shl esi, 4
sub edi, esi ; edi = new sp
shr esi, 4
pop bx ; segment of int handler
pop ax ; offset of int handler
push esi ; ss
push edi ; sp
push ecx ; FLAG
and ebx, 0000ffffh
push ebx
and eax, 0000ffffh
push eax
iret
Mir ist ein Rätsel warum BOCHS den iret Befehl ohne erneute Exception ausführt aber das in der Realität nicht so ist. Aber das mit BOCHS ist ja sowieso eine eigene Geschichte.
Das VM-Bit im gepushten (E)FLAG ist auf jeden Fall gesetzt, sodas auch gewähleistet ist, dass wieder in den V86-Mode umgeschaltet wird.