CS:IP im Programm ändern
-
Hallo zusammen,
Ich schreibe .com Programme unter DOS.
Nun möchte ich einen Programmteil an eine neue Adresse kopieren und dort zur
Ausführung bringen.. dazu muss ich irgendwie cs:ip ändern.Dazu hab ich den zu verschiebenden Code zwischen zwei Labels geschrieben, um genau diesen Abschnitt zu kopieren..
In einer Variable speichere ich die Größe in Byte zwischen den Labels.mov es, 09F00h ;neue Segmentadresse
xor di, di
mov si, offset start_r ;erstes Label vor dem Code
mov cx, size_r ;Abstand zwischen den Labels
rep movsbDas kopieren wird anstandslos ausgeführt.
Nun aber soll gesprungen werden.
mov ax, 09F00h
mov cs, axsomit ist cs schonmal angepasst.
nun fehlt mir der Sprung an die neue Adresse...
jmp verlangt immer ein Label als Ziel aber alle Labels haben Adressen aus dem Segment der .com Datei.Was fehlt mir denn noch für den Sprung dorthin?
Danke und Gruß
Nicky
-
push segment push offset retf
-
Zum Setzen des Instruktionszeigers (nur ip oder auch cs:ip als Ganzes) gibt es beim x86 Sprung- (jmp), Prozedur- (call), und Interruptaufrufbefehle (int) sowie Ruecksprungbefehle (ret).
Fuer dein Problem koenntest du z.B. einen absoluten far-Jump-Befehl benutzen.
-
Hallo...
und dieser direkte Far-Jump ist der "retf" Befehl?
ich versuch es morgen weiter... hat bis jetzt noch nicht funktioniert..
Danke erstmal..
Nicky
-
Es hilft im übrigens auch, sich mal den ein oder anderen Interrupt genauer anzuschauen, man kann so einiges lernen, aber nicht bei VMs, sondern wirklichem realen Dosbetriebssystem.
Far Jumps bzw. Far Returns brauchen eine zusätzliche Adressenspeicherung, nämlich die richtige Rücksprungaddi ins passende Segment.
Den Instruction Pointer kann man selbst nicht im Programm ändern. Und vielleicht müsste man sich mal anschauen, wie Real Mode Adressen berechnet werden UND wie das Betriebssystem Dos selbst Ladeadressen berechnet.
-
supernicky schrieb:
Hallo...
und dieser direkte Far-Jump ist der "retf" Befehl?
Nicky
Das hängt mit den vereinfachten MODEL-Direktiven zusammen. TASM z.B. erlaubt dann keine direkten ("immediate") FAR-Sprünge (MASM glaub' ich auch). Du kannst aber die Segmente auch per Hand deklarieren. Vollständiges Beispiel für TASM (COM-File):
SEGMENT _TEXT ORG 0100h Start: mov ax, SEG FAR_AWAY mov es, ax ;neue Segmentadresse xor di, di mov si, offset start_r ;erstes Label vor dem Code mov cx, size_r ;Abstand zwischen den Labels rep movsb jmp Target start_r: mov ax, 4C00h int 21h size_r EQU $-start_r ENDS SEGMENT FAR_AWAY AT 09F00h Target label far ENDS END Start
Und nun darfst Du Dich entscheiden, ob der RETF-Trick nicht doch bequemer ist
.
viele grüße
ralph
-
Hallo nochmal,
ich habe es hinbekommen...
Ein Stück Programmcode wird an eine andere Stelle im Ram kopiert und dort ausgeführt.
Danke an alle...
Nicky