Borland x86 inline-assembler ist, erhalten eine label-Adresse?
Ich bin mit Borland Turbo C++ mit einigen inline-assembler-code, so dass vermutlich der Turbo Assembler (TASM) Art Assembler-code. Ich möchte Folgendes tun:
void foo::bar( void )
{
__asm
{
mov eax, SomeLabel
//...
}
//...
SomeLabel:
//...
}
Also die Adresse von SomeLabel, wird in EAX. Dies funktioniert nicht und der compiler meckert: Undefined symbol "SomeLabel'.
In Microsoft Assembler (MASM) beschrieben, das dollar-symbol ($) dient der aktuellen Position-Zähler, das wäre nützlich für meine Zwecke. Aber auch dies scheint nicht zu funktionieren, in Borland Assember (Ausdrucks-syntax-Fehler).
Update: ein bisschen konkreter, ich brauche den compiler generiert die Adresse, bewegt es sich in eax als eine Konstante bei der Kompilierung/Verlinkung und nicht zur Laufzeit, so wird es zu kompilieren, wie "mov eax, 0x00401234".
Kann jemand empfehlen, wie man diese arbeiten?
UPDATE: Antworten auf Pax die Frage (siehe Kommentar), Wenn die Basis-Adresse wird zur Laufzeit geändert durch den Windows-loader die DLL/EXE PE Bild wird noch verschoben werden, indem Sie die Windows-Ladeprogramm und die Etiketten-Adresse gepatcht werden, die zur Laufzeit vom loader zu verwenden, die re-basiert-Adresse, so dass die Verwendung eines Compiler - /link-Zeit-Wert für den label-Adresse ist nicht ein Problem.
Vielen Dank im Voraus.
- Funktioniert das, wenn Sie definieren SomeLabel innerhalb der asm-block?
- für gcc, immer eine Etiketten-Adresse ist "&&label", haben Sie es ausprobiert? vielleicht klappt es bei borland auch?
- Wie genau wollen Sie, um den Wert zur compile-Zeit? Der loader kann sich ändern (zur Ladezeit, lange nach Links) die Adresse, an der dieser code wird geladen, so dass Sie Ihren Compiler - /link-Wert nutzlos.
- Vielleicht müssen Sie nochmals die Frage: was GENAU willst du mit eax, sobald es geladen ist.
- paxdiablo: Die Windows-PE-loader zu verlagern, eine exe-Datei und Prozess der PE-Dateien .reloc Abschnitt aktualisieren von einer festen Adresse mit der neu geladenen base-Adresse, damit EAX würde immer richtig sein. Auch sollte es nicht, egal was ich tun werde mit EAX, sobald es geladen ist, die Frage ist, wie setzen EAX die Adresse SomeLabel (was leicht möglich ist, in MSVC einfach nicht C++ Builder).
Du musst angemeldet sein, um einen Kommentar abzugeben.
Letzten Zeit habe ich versucht, einige Assembler-code Borland-kompatibel stieß ich auf die Einschränkung, dass man nicht vorwärts-Referenz labels. Nicht sicher, ob das, was läufst du hier.
Alles, was ich finden kann über Borland empfiehlt diese sollten auf die Arbeit. Ähnliche Fragen, die auf anderen Websites (hier und hier) deuten darauf hin, dass Borland verarbeiten kann vorwärts-Referenzen für Zeichen, sondern besteht auf Etiketten, außen-asm-Blöcken. Jedoch, wie Ihr label war bereits außerhalb der asm-block...
Ich bin neugierig, ob Ihr compiler würde Ihnen erlauben, diese Bezeichnung verwenden, beispielsweise in einer jmp-Anweisung. Wenn Sie spielen, um mit es (zugegebenermaßen auf einem ganz anderen compiler), fand ich einen lästigen Tendenz, dass der compiler beschweren sich über Operanden-Typen.
Die syntax ist ganz anders, und es ist mein Erster Versuch in inline-asm in eine lange Zeit, aber ich glaube, ich habe verwurschtelt dies genug, um die Arbeit unter gcc. Vielleicht, trotz der Unterschiede, dies könnte einige nutzen für Sie:
Diesem generiert:
Den && - operator ist ein nicht-standard-Erweiterung, würde ich nicht erwarten, dass es funktioniert überall anders als gcc. Hoffentlich kann diese gerührt, bis ein paar neue Ideen... viel Glück!
Edit: Obwohl es ist aufgeführt als Microsoft-spezifische, hier ist ein weiteres Beispiel springen auf Etiketten.
3 Vorschläge:
1) setzen Sie einen '_' vor dem SomeLabel in der Montage-so wird es "mov eax, _SomeLabel
". In der Regel wird der compiler hinzufügen, wenn es übersetzt C in der Montage.
Oder
2) legen Sie die label in einer Baugruppe Abschnitt. Dies verhindert, dass der compiler aus der addition der '_'.
Oder
3) kommentieren Sie die assembly kompilieren und schauen Sie in die listing-Datei (*.lst), um zu sehen, was der label-name wird.
Funktioniert der Turbo-C++ - Umgebung eine Möglichkeit haben, legen Sie die Optionen für TASM (ich weiß, dass einige von der Borland-IDEs haben)?
Wenn ja, sehen Sie, wenn Sie die option "Maximale Anzahl an Durchläufen (/m)" auf 2 oder mehr hilft (könnte es standardmäßig auf 1-pass).
Auch, wenn Sie eine lange Bezeichnung, die vielleicht ein problem darstellen - zumindest eine IDE hatte das Standard-set bis 12. Ändern Sie die "Maximale Zeichen Länge (/mv) - option".
Diese information basiert auf Borland-IDE von RAD Studio:
Ein paar mehr Dinge (Aufnahmen im Dunkeln) zu versuchen:
sehen, ob mit der folgenden Montageanleitung hilft:
meisten Compiler erzeugen kann eine assembly code, den Sie generieren (nicht sicher, wenn Turbo C++ kann, da Codegear/Embarcadero position, die Sie als eine freie, nicht-professionellen compiler).
Versuchen Herstellung eine Liste mit C-code, der über eine mit einem label (als
goto
Ziel zum Beispiel), mit einigen inline-Montage in der gleichen Funktion, aber nicht versuchen, auf das Etikett von der Montage. Dies ist, so können Sie ein compiler ohne Fehler und mit einer Liste der assembly. So etwas wie:Blick auf die Liste der assembly und sehen, ob die generierte assembly schmückt den label-Namen in einer Weise, dass Sie vielleicht in der Lage zu replizieren, die in die inline-Montage.
Von was ich mich erinnere, können Sie nicht verwenden, ein externes (C++ -) Aufkleber in Ihrem inline-assembly, obwohl Sie haben können, TASM-Stil-Etiketten, die in den asm-block, auf die verwiesen werden kann, die von der bauanleitung selbst. Ich denke, ich würde eine fahne und eine post-assembler switch-Anweisung zu behandeln Verzweigung. Zum Beispiel:
Ich weiß nicht, was dein compiler /assembler-spezifisch, sondern ein trick, den ich verwendet habe, durchaus etwas ist, rufen Sie die nächste Position, und dann knallen Sie die Stapel in Ihre register. Sicher, dass der Anruf, den Sie machen, nur drückt die return-Adresse.
Ich denke, das problem Sie laufen in ist, dass ein Aufkleber auf der Innenseite der
__asm
block und die label im C++ - code sind zwei völlig verschiedene Dinge. Ich würde nicht erwarten, dass Sie könnte eine Referenz der C++ - label auf diese Weise aus der inline-Montage, aber ich muss sagen, es ist schon eine sehr lange Zeit, da ich habe Turbo C++.Haben Sie versucht, die
lea
- Anweisung stattmov
?Nur raten, da ich noch nicht verwendet inline assembler, mit C/++ compiler...
Weiß ich nicht die genaue syntax von TASM.
Dies ist eine Variante von Iwan ' s Vorschlag aber geben Sie diesem einen Versuch:
Hier ist eine mögliche Methode:
Es ist ein bisschen hacky, aber es funktioniert in der version von Turbo C++, die ich habe. Es fast sicher ist abhängig von der compiler-Optimierung und-Einstellungen.
eine der Möglichkeiten wäre die Verwendung von separaten "nackt" (prolog-weniger) Verfahren SomeLabel anstelle von label -