Ich konnte MASM nicht dazu bringen, eine Far-Call-Anweisung zu akzeptieren, die als call 0f000h:1260h
geschrieben wurde, wahrscheinlich wegen der Probleme, die in diese Frage .
Anstatt mich mit kryptischen MASM-Direktiven herumzuschlagen, entschied ich mich, sie manuell in mein Programm zu schreiben, indem ich die DB wie folgt benutze:
%Vor% Beim Durchlaufen des Programms mit DEBUG.COM habe ich festgestellt, dass nach der Ausführung der Aufrufanweisung "DB FE" erscheint. Dies tritt jedoch nicht auf, wenn int 1ch
ausgeführt wird. Was ist der Unterschied zwischen diesen beiden Methoden, zum Standort f000 zu springen: 1260?
Ich nahm an, dass DEBUG 0xfe (zusammen mit den folgenden Bytes) nicht als gültigen Opcode erkannte. Ich habe den Standort f000: 1260 gelöscht, um zu sehen, welche Bytes dort waren.
Byte 0xfe ist tatsächlich vorhanden, zusammen mit einigen anderen Bytes. Ich weiß, dass 0xcf an sich der Opcode für IRET ist (was alles ist, was ich erwartet habe), also was sind diese anderen Bytes?
Hier ist der IVT-Eintrag für int 1ch
am Standort 0000: 0070.
AKTUALISIEREN
Wie Michael Petch in seiner Antwort sagte, bilden die seltsamen Bytes einen Rückrufmechanismus in DOSBox. Ich war neugierig zu sehen, was passieren würde, wenn ich versuchen würde, diesen Rückruf in meinem Hauptprogramm auszuführen.
Ausführen:
%Vor%Scheint genauso zu sein wie die Ausführung von:
%Vor% Der einzige Unterschied ist, dass int
FLAGS
, CS
und IP
drückt und IF und TF löscht. Das Programm wird an einen IRET (an der Stelle f000: 1264) zurückgegeben, der all dies rückgängig macht.
"DB FE" wird weiterhin in DEBUG angezeigt. Ich denke, der Callback wird nur durch die Kombination von 0xfe und 0x38 ausgelöst. Es versucht zuerst 0xfe auszuführen, was in diesem Fall nicht Teil eines gültigen Opcodes ist und nichts tut (0xfe ist Teil von inc
opcode, wenn gültige Bytes folgen), dann tritt der Callback auf, wenn die folgende 0x38 auftritt.
0xFE 0x38
ist kein definierter Präfix und / oder Befehl auf einem echten Intel x86-Prozessor. In DOSBox ist die Sequenz 0xFE 0x38
eine spezielle 4-Byte-Anweisung. Die verbleibenden zwei Byte bilden einen 16-Bit-Wert, der als DOSBox-Rückrufindexnummer fungiert. In diesem Fall lautet der Index 0x0013
.
Was dies effektiv tut, ruft DOSBox selbst auf, um die angeforderte Aufgabe auszuführen. DOSBox wird alle erforderlichen Verarbeitungen ausführen, setzt die Register im Emulator und kehrt dann zurück. Die nächste Anweisung ist IRET
(0xCF). Das beendet den Interrupt und setzt die Verarbeitung der Anweisungen vor dem Interrupt-Aufruf fort.
Ich entdeckte dies, während ich den DOSBox-Code betrachtete. Insbesondere die Funktion CALLBACK_SetupExtra
:
Dieser Code richtet DOSBox-Callbacks ein, bei denen nach dem Rückruf ein IRET
benötigt wird.