Jmp mit NASM

Diskussion zum Thema Programmierung unter DOS (Intel x86)
Antworten
TomCat
MemMaker-Benutzer
Beiträge: 87
Registriert: Do 1. Dez 2011, 17:16

Jmp mit NASM

Beitrag von TomCat »

Hallo,

bin neu mit NASM.

es gibt den Befehl:
jmp 0x2000:0x0000

hier wird einfach an die Adresse gesprungen.

wie kann ich das im Porgrammcode flexibel gestalten, also dass relativ von Speicher oder Register-Inhalten gesprungen wird.

z.b.
mov ax, 0x2000
mov bx, 0x0000
jmp [ax]:[bx]

leider nimmt das der Compiler nicht. :-((
Wie kann man das bewerkstelligen?

THX
Benutzeravatar
Dosenware
DOS-Gott
Beiträge: 3745
Registriert: Mi 24. Mai 2006, 20:29

Re: Jmp mit NASM

Beitrag von Dosenware »

z.b.

Mov [@Marke+1],ax
Mov [@Marke+3],bx
@Marke
JMP $0000:0000

sofern der Opcode von JMP ein byte groß ist, überschreibt der Mov die Sprungadresse, ist der Opcode zwei bytes groß muss da halt [@Marke+2] und [@Marke+4] stehen.

ansonsten kannst du dir auch den Thread anschauen: http://www.dosforum.de/viewtopic.php?f= ... JMP#p38055
TomCat
MemMaker-Benutzer
Beiträge: 87
Registriert: Do 1. Dez 2011, 17:16

Re: Jmp mit NASM

Beitrag von TomCat »

Hi,

danke, aber leider funzt das nicht. Also auch in der anderen Variante nicht.
Es muss doch möglich sein das CS-Segmentregister und den IP-Pointer flexibel zu setzen und nicht nur starr mit
jmp 0x2000:0x0000 ??
idspispopd
Norton Commander
Beiträge: 108
Registriert: Fr 8. Mai 2015, 22:28
Wohnort: Hamburg

Re: Jmp mit NASM

Beitrag von idspispopd »

Bei einem NEAR-Jump kannst Du die Zieladresse tatsächlich in einem Register stehen haben, aber bei einem FAR-Jump (so nennt sich das was Du möchtest) kann die Zieladresse nur direkt (immediate) angegeben werden oder im Speicher stehen.
Selbstmodifizierenden Code braucht man dafür jedenfalls nicht.
Das müsste ungefähr so gehen, ohne dass ich das jetzt ausprobieren kann:

Code: Alles auswählen

jmp [Ziel]
Ziel:
dw 0x0000,0x2000
Die Zieladresse kannst Du natürlich vorher durch Dein Programm ändern lassen.
TomCat
MemMaker-Benutzer
Beiträge: 87
Registriert: Do 1. Dez 2011, 17:16

Re: Jmp mit NASM

Beitrag von TomCat »

Leider funktioniert das auch nicht. Er springt einfach nicht an die gewünschte Adresse!

Es geht mir darum von einem eigenen Kernel ein Programm in den Speicher zu laden und dann den IP und CS auf den Programmanfang zu setzen. Da ich den Einsprung nicht vorher kenne, kann ich nicht einfach:
jmp 0x2000:0x0000 schreiben.
idspispopd
Norton Commander
Beiträge: 108
Registriert: Fr 8. Mai 2015, 22:28
Wohnort: Hamburg

Re: Jmp mit NASM

Beitrag von idspispopd »

Aber er springt schon mal irgendwo hin? Dann könntest Du mal mit dem Debugger gucken wohin denn gesprungen wird, vielleicht ist die Adresse ja falsch gespeichert. Ich hatte mal getippt dass zuerst der Offset und dann das Segment kommen muss, aber 100%ig würde das nicht beschwören.
DOSferatu
DOS-Übermensch
Beiträge: 1220
Registriert: Di 25. Sep 2007, 12:05
Kontaktdaten:

Re: Jmp mit NASM

Beitrag von DOSferatu »

Es gibt einen ganz einfachen Trick, mit dem man einen Sprung an eine FAR Adresse machen kann (hab ich auch schon benutzt)
Schon mal an einen FAR RET gedacht?
Man speichert Segment und Offset (in dieser Reihenfolge!) auf den Stack und führt einen FAR RET aus - schon ist man an der richtigen Adresse. (Man kann natürlich auch beide Words zusammen als DWord pushen, mit 32bit-Befehl.)

Daß man CS nicht "laden" kann, hat einen Sinn: Man befindet sich ja gerade im Codebereich, der durch dieses Register "definiert" wird. Deshalb gibt's keinen POP CS Befehl (PUSH CS gibts). (Die Stelle, wo dieser nach der Logik stehen würde, wurde als Präfix für die 2-Byte-Befehle benutzt.)
Und: Es gibt zwar die MOV Segmentregister,X Befehle - ABER: Es macht nicht viel SInn, CS und IP getrennt zu setzen (wobei man IP sowieso nicht "setzen" kann). Sobald eins von beiden gesetzt ist, das andere noch nicht, befindet man sich an einer "halben" Adresse (halb neu, halb alt) und der nächste Befehl würde schon da ausgeführt werden. Daher muß natürlich ein FAR JUMP mit nur EINEM Befehl ausgeführt werden.

Ich denke, das sollte das Problem lösen. DIeser "Rücksprung" ist somit eigentlich kein wirklicher Rücksprung, sondern funktioniert eben wie ein Sprung.

Anmerkung: Natürlich ist auch ein "indirekter" FAR JMP auf der x86 CPU vorgesehen, also so, daß man die ADRESSE, an der die eigentlichen 2 Words (IP:CS) im Speicher liegen, als Parameter angibt. Der Opcode für diesen FAR JMP ist $FF, gefolgt dann natürlich wieder vom entsprechenden Mod-R/M Byte und evtl einem Displacement-Word - wenn die Adresse nicht im DS liegt (oder SS, wenn man u.a. BP als Index benutzt), dann natürlich mit dem entsprechenden Segmentpräfix davor.
Was es NICHT gibt, ist lediglich ein JMP, dem man zwei Register-Parameter geben kann, für Offset und Segment.

Kleine Zusatzbemerkung meinerseits mal wieder:
Mit "Stack-Sprüngen" habe ich gerade in meinem GameSys2 ganz witzige Dinge angestellt. Man kann damit etwas Rechenzeit sparen. z.B. wenn man an einen Programmteil A springt und dieser ruft seinerseits Subroutinen B auf. Wenn das allerletzte, was die Programmteil A macht, der Aufruf einer Subroutine B ist, und danach nur ein Sprung/Rücksprung folgen würde, PUSH ich diese Rücksprungadresse auf den Stack und SPRINGE dann zu Subroutine B (also kein CALL, sondern JMP). Der RET der Subroutine B springt dann gleich wieder zurück... - So spart man sich CALLs und vor allem den "Doppelsprung" am Ende.
Wenn man sich ein wenig auskennt, kann man mit dem Stack lustige Dinge anstellen...
idspispopd
Norton Commander
Beiträge: 108
Registriert: Fr 8. Mai 2015, 22:28
Wohnort: Hamburg

Re: Jmp mit NASM

Beitrag von idspispopd »

DOSferatu hat geschrieben:Daß man CS nicht "laden" kann, hat einen Sinn: Man befindet sich ja gerade im Codebereich, der durch dieses Register "definiert" wird. Deshalb gibt's keinen POP CS Befehl (PUSH CS gibts). (Die Stelle, wo dieser nach der Logik stehen würde, wurde als Präfix für die 2-Byte-Befehle benutzt.)
Fast richtig: 8086 und 8088 haben den Opcode tatsächlich als POP CS interpretiert. Später hat Intel dann wohl gemerkt dass man das eigentlich nicht braucht und den Opcode umgewidmet,
TomCat
MemMaker-Benutzer
Beiträge: 87
Registriert: Do 1. Dez 2011, 17:16

Re: Jmp mit NASM

Beitrag von TomCat »

Vielen vielen Dank !!!

das mit:
push ax
push bx
retf

funktioniert perfekt !!!
Antworten