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 movsb

    Das kopieren wird anstandslos ausgeführt.

    Nun aber soll gesprungen werden.

    mov ax, 09F00h
    mov cs, ax

    somit 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.

    http://en.wikipedia.org/wiki/Relocation_(computer_science)



  • 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


Anmelden zum Antworten