Archiv verlassen und diese Seite im Standarddesign anzeigen : mal wieder zuviel code
blablabla
13.07.2001, 00:27
also ich happ folgendes z.b.
cmp eax,0
je penner
mov edx,0
penner:
...
soo, jetzt schnapp ich mir doch gleich mal wieder nen dissassembler:D und siehe da zwischen mov edx,0 und der sprungmarke packt der mir NOP's rein...ich denke mal das lieg an der ausrichtung an 4byte adressen oder so....wie krieg ich das wech? (der code wird dadurch ziemlich groß!)
LostMind
14.07.2001, 01:54
Hi,
exakt dieses Problem hatte ich auch - allerdings nur in Verbindung mit TASM und TLINK.
Ich vermute mal, der Linker versucht damit das Sprungziel auf gerade Adressen zu legen, was mit geringen Geschwindigkeitsvorteilen verbunden ist... naja, die NOP's müßtest du wegbekommen, indem du einfach schreibst:
JMP SHORT Sprungmarke
Zumindest hat das bei mir geholfen.
MFG
LostMind
Wenns innerhalb von +/- 128 Bytes liegt, sollte das gehn, aber was, wenn nicht?
Man müsste doch dem TASM/TLINK sagen können, ob er ausrichten soll oder nicht.
Geht nicht ".align 1" oder sowas?
LostMind
14.07.2001, 13:38
Hi,
zumindest bei mir hat das keinen Effekt auf die NOP's - ich glaube die ALIGN Direktive bezieht sich nur auf die Ausrichtung von Variablen, allerdings habe ich auch eine sehr alte TASM und TLINK Version, vielleicht ist das inzwischen anders...
MFG
LostMind
blablabla
14.07.2001, 15:56
was is denn der unterschied zu
JMP blabla
JMP SHORT blabla?
kann ich auch schreiben
je short blabla?
Ich glaub auch nicht das mit jmp zu tun hat. Ich kenne das NOP hinter jmp eigentlich nur von Bootsektoren. Da früher ja jmps auch drei Byte lang sein konnten, restviert man einfach ein Byte, für den Fall der Fälle. Wofür man das heute macht, weiß ich auch nicht. Wahrscheinlich auch ne arte Marke geworden. Außerdem was soll das den für ein Geschwindigkeitsvorteil sein, wenn man tausend NOPs in den Arbeitspeichern mehr laden muss? Dafür brauchst du aber schon ne große Schleife damit sich das lohnt, oder sehe ich das falsch?
Vielleicht führt der ne Normalisierung auf Paragraphs durch.
Das wird eigentlich gemacht damit man mit verschieden Segemt-Offset-Kombinationen, nicht die Gleiche Adresse ansprechen kann.
[Dieser Beitrag wurde von BunnyR81 am 14. Juli 2001 editiert.]
Das mit den NOPs ist alignment, so eine Art Optimierung, hat mit Cache und Prefetch zu tun. Ich glaube Tasm richtet sowas an durch 4 teilbaren Adressen aus, was sowieso nicht viel bringt. Nur bei 16/32 byte Ausrichtung eigentlich, und nur bei Loops die oft ausgeführt werden würde ich sagen.
Das mit dem jmp short, hm, keine Ahnung warum das dann klappt... Normalerweise sind jumps <= 127 doch sowieso short.
Wie man das abstellt weiß ich leider auch nicht... Hat irgendwer das Handbuch zu Tasm? i. e. hat ihn irgendjemand gekauft? ;-)
Jumps < 128 Bytes macht er bei mir nicht automatisch short, nur wenn ich ihm das extra angeb... weiß auch nicht warum *g*
LostMind
15.07.2001, 02:01
Hi,
ich hätte für das NOP auch noch eine andere (logischere) Erklärung. Weil das NOP immer erzeugt wird und das direkt nach dem Jump, kann es mit Alignment eigentlich nix zu tun haben. Ich vermute daher mal folgendes (nur ne These, muß nicht stimmen):
Der Assembler kennt bei der Übersetzung des Programms noch nicht die Länge des Bereichs bis zur angegebenen Sprungmarke (da er diesen erst noch übersetzen muß bzw. verschiedene Abhängigkeiten darin erst nach Übersetzung des Restes bekannt sind, z.B. relative Sprungziele)
Deshalb erzeugt der Assembler erstmal standardmäßig einen Jump, mit dem er auch den größtmöglichen Bereich innerhalb des Segments abdecken kann, sprich nen NEAR Jump. Wenn sich nun im Verlauf der Übersetzung herausstellt, daß der Bereich kleiner ist, und man auch einen SHORT Jump hätte nehmen können, wurde der Bereich (und damit die ganzen Labels und Sprungmarken darin) ja schon übersetzt. Da ein SHORT Jump kürzer ist (nur 2 Bytes inkl. Opcode) müßte der Assembler den ganzen Bereich nochmals übersetzen, weil sich bei kürzerem Befehl die ganzen Abhängigkeiten (relative Sprungziele etc.) ändern würden. Bei mehreren Jumps und den vielen Abhängigkeiten in Form von Labels und Relativen Adressen kann dieses Vorgehen erheblich Zeit kosten. Ich vermute daher, daß der Assembler in einem solchen Fall zwar den kürzeren (und schnelleren) SHORT Jump nimmt, aber um die ganzen Abhängigkeiten nicht wieder neuberechnen zu müssen, das dritte, unbenutzte Byte, was bei einem NEAR Jump nötigt gewesen wäre, einfach mit einem NOP belegt.
Ende der Theorie. Ach, das Leben könnte so einfach sein... ;-)
MFG
LostMind
[Dieser Beitrag wurde von LostMind am 15. Juli 2001 editiert.]
Klingt eigentlich noch logischer. Aber ist eigentlich Pfusch von Assembler, weil der Code ja so unnötig größer wird *g*
Nein, das kann ich mir kaum vorstellen... Deswegen ist Tasm ja ein Multi-Pass Assembler, damit er solche Sachen optimieren kann. Er läuft also mehrmals über den Code, bis diese Sachen komplett aufgelöst sind. Das ist wirklich wegen dem Alignment. Die NOPs werden außerdem vor dem Label eingesetzt, nicht nach dem Sprung... Oder?
LostMind
15.07.2001, 17:53
Die NOPs werden außerdem vor dem Label eingesetzt, nicht nach dem Sprung... Oder?
Zumindest bei mir nicht - das NOP steht nach dem Jump, habs nochmal getestet.
Deswegen ist Tasm ja ein Multi-Pass Assembler
Hm, zumindest meine Uralt Version is nur n Einpass ASM (1.01 / 2.0)
Aber ich gebe dir recht, im Fall von blablabla scheint es wirklich am Alignment zu liegen, da die NOP's vor der Sprungmarke stehen. Aber wie gesagt, wenn das mit ner älteren TASM Version assembliert und gelinkt würde, käme nochmals ein NOP nach dem Jump hinzu, was sich mit besagter Methode verhindern ließe.
MFG
LostMind