PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : x86 Assembler: JMP Problem "short jump is out of range"


mf_2
2004-04-12, 16:00:17
Hallo,

ich möchte in einem Assembler Prog zu einer Routine
ausgabe:
springen.
dazwischen steht noch n Haufen anderes Zeug, das im Verlaufe der Entwicklung immer länger geworden ist.
Seit kurzem meldet mir NSAM bei der Kompilierung immer folgendes:
short jump is out of range
Wie kann ich denn aus dem short jump einen längeren machen?
Ich hab einfach nur "jmp ausgabe" angegeben, was muss ich angeben, dass ich weiter springen kann?

zeckensack
2004-04-12, 16:30:32
jmp near

Das hat normalerweise volle 32 Bit Reichweite, es sei denn du schreibst für 286er und/oder für den Real mode (DOS/Bootloader uä).

mf_2
2004-04-12, 16:44:16
Original geschrieben von zeckensack
jmp near

Das hat normalerweise volle 32 Bit Reichweite, es sei denn du schreibst für 286er und/oder für den Real mode (DOS/Bootloader uä).

Leider schreibe ich für den RealMode und das Programm soll auch auf einem 8086/80286 laufen. Geht das da auch und wenn nicht, was muss ich dann nehmen?

zeckensack
2004-04-12, 17:18:41
Original geschrieben von mf_2
Leider schreibe ich für den RealMode und das Programm soll auch auf einem 8086/80286 laufen. Geht das da auch und wenn nicht, was muss ich dann nehmen? jmp far
Da gibt's zwei Varianten, entweder mit immediatesjmp far word 0x1234:0x2345 ;Segment=0x1234, Offset=0x2345oder indirekt über eine Speicheradressse (die dann Segment:Offset enthält).SECTION .data
far_call_address:
dw 0x2345 ;offset
dw 0x1234 ;segment

SECTION .code
jmp far word [far_call_address]Bitte dringend beachten: eine via call far angesprungene Funktion muss mit retf verlassen werden.

Daten in anderen Segmenten sind auch noch speziell zu berücksichtigen. Ich kann dir nur empfehlen, dir die Dokumentation (http://prdownloads.sourceforge.net/nasm/nasm-0.98.38-xdoc.zip?download) mal anzuschauen.
Wichtige Schlüsselwörter: SEG, WRT, "Effective Address", "NASM Doesn't Support Memory Models", SECTION, BITS, und natürlich die Instruktionsreferenz im Anhang. Sehr empfehlenswert ist auch das gesamte Kapitel 7 "Writing 16-bit Code (DOS, Windows 3/3.1)".

Ich hoffe du weisst was du da tust :)

HajottV
2004-04-12, 17:26:32
War Zecki schneller.

mf_2
2004-04-12, 17:38:15
Muss man zwangsläufig irgendeine statische Adresse für den Sprung angeben?
Wie kann ich die bestimmen?
Wenn z.B. eine Routine "ausgabe:" irgendwo in meinem Quelltext drin steht, wie bekomme ich dann die Adresse von der Routine?
Das peil ich irgendwie nicht.

zeckensack
2004-04-12, 18:09:20
Original geschrieben von mf_2
Muss man zwangsläufig irgendeine statische Adresse für den Sprung angeben?
Wie kann ich die bestimmen?
Wenn z.B. eine Routine "ausgabe:" irgendwo in meinem Quelltext drin steht, wie bekomme ich dann die Adresse von der Routine?
Das peil ich irgendwie nicht. Du musst sie nicht wissen. Du kannst "call far ausgabe" machen, und der Assembler setzt die korrekte Adresse ein.
Aber ... das Problem ist nicht unbedingt die Syntax, sondern die Limitierung einzelner Segmente auf 64kiB. Du musst deinen Code irgendwie so aufteilen, dass du diese Begrenzung einhältst, sprich, du musst ab einer gewissen Grenze mehrere Code-Segmente anlegen lassen.
BITS 16
SECTION .code0

funktion:
shr AX,1
retf

SECTION .code1

andere_funktion:
mov ax,5
call far funktion
<...>

SECTION .code0
kaputt:
mov ax,5
call near funktion ;crash
Problem:
funktion wird von einem anderen Segment aus aufgerufen, daher muss sie mit retf enden. Das bedeutet nun aber auch, dass sie nur noch mit call far anzuspringen ist, auch wenn sie vom gleichen Segment aus aufgerufen wird. Wenn du Code von einem einzelnen Code-Segment auf mehrere Code-Segmente "aufrüstest", musst du also sehr penibel alle alten Funktionen nochmal durchsehen und entsprechend anpassen, sonst passieren Dinge(TM).

mf_2
2004-04-12, 21:08:38
Das Problem taucht also auf, weil mein Programm über zwei Segmente geht, oder? Ein Segement ist ja 64 KB lang, mein Programm ist baer höchstens 2 KB lang, hat der NASM evtl. eine falsche Größeneinstellung für die Segmente o.ä.?
Das Programm ist definitiv nicht größer als 64 KB, also dürfte es eigentlich auch beim Springen im Programm keine Probleme geben, somit müsste es doch an NASM liegen?
Kennt ihr so ein Problem mit dem NASM?

zeckensack
2004-04-12, 21:25:28
Original geschrieben von mf_2
Das Problem taucht also auf, weil mein Programm über zwei Segmente geht, oder? Ein Segement ist ja 64 KB lang, mein Programm ist baer höchstens 2 KB lang, hat der NASM evtl. eine falsche Größeneinstellung für die Segmente o.ä.?
Das Programm ist definitiv nicht größer als 64 KB, also dürfte es eigentlich auch beim Springen im Programm keine Probleme geben, somit müsste es doch an NASM liegen?
Kennt ihr so ein Problem mit dem NASM? Eigentlich nicht :|
Hast du oft "zwischendrin" Daten im Code? Also RESB/RESW/RESD, DB, DW, DD zwischen den Funktionen?

mf_2
2004-04-13, 21:24:01
Ich hab jetzt mal alle Textmessages die ich so im code hatte ( alles db strings ) ans ende der datei kopiert und jetzt geht es auch mit den ganz normalen JMP sachen ohne call far etc.