Ich verwende Borland Turbo C ++ mit etwas eingebautem Assembler-Code, also vermutlich Assembler-Code im Turbo Assembler (TASM). Ich möchte Folgendes tun:
%Vor%Also wird die Adresse von SomeLabel in EAX gelegt. Dies funktioniert nicht und der Compiler beschwert sich: Undefiniertes Symbol 'SomeLabel'.
In Microsoft Assembler (MASM) dient das Dollarsymbol ($) als aktueller Positionszähler, was für meinen Zweck nützlich wäre. Aber auch das scheint in Borlands Assember nicht zu funktionieren (Ausdruckssyntaxfehler).
Update: Um etwas genauer zu sein, brauche ich den Compiler, um die Adresse, die er in eax bewegt, als eine Konstante während der Kompilierung / Verknüpfung und nicht zur Laufzeit zu generieren, so wird es wie "mov eax, 0x00401234" kompilieren / p>
Kann jemand vorschlagen, wie das funktioniert?
UPDATE: Um auf die Frage von Pax zu antworten (siehe Kommentar), Wenn die Basisadresse zur Laufzeit vom Windows-Loader geändert wird, wird das DLL / EXE-PE-Image immer noch vom Windows-Loader verschoben und die Label-Adresse wird gepatcht Laufzeit durch den Loader, um die re-basierte Adresse zu verwenden, so dass die Verwendung eines Kompilierungs- / Link-Zeitwerts für die Label-Adresse kein Problem darstellt.
Vielen Dank im Voraus.
Alles, was ich über Borland herausfinden kann, legt nahe, dass dies funktionieren sollte. Ähnliche Fragen auf anderen Websites ( hier und hier ) legen nahe, dass Borland Vorwärtsreferenzen für Etiketten handhaben kann, besteht aber darauf, dass Etiketten außerhalb von ASM-Blöcken sind. Da sich Ihr Label jedoch bereits außerhalb des ASM-Blocks befand, ...
Ich bin neugierig, ob Ihr Compiler Ihnen erlauben würde, diese Bezeichnung zum Beispiel in einer jmp-Anweisung zu verwenden. Als ich damit herumspielte (zugegebenermaßen auf einem komplett anderen Compiler), fand ich eine nervtötende Tendenz, dass der Compiler sich über Operandentypen beschwerte.
Die Syntax ist ziemlich anders, und es ist mein erster Versuch inline asm seit langer Zeit, aber ich glaube, ich habe genug genug, um unter gcc zu arbeiten. Vielleicht könnte Ihnen dies trotz der Unterschiede von Nutzen sein:
%Vor%Dies erzeugt:
%Vor%Die & amp; & amp; Operator ist eine nicht-standard-Erweiterung, ich würde nicht erwarten, dass es anders als gcc funktioniert. Hoffentlich hat das einige neue Ideen hervorgebracht ... Viel Glück!
Bearbeiten: Obwohl es als Microsoft spezifisch aufgeführt ist, ist hier eine weitere Instanz, um zu Labels zu springen .
3 Vorschläge:
1) setzen Sie ein '_' vor das SomeLabel in der Assembly, so dass es "mov eax, _SomeLabel "Normalerweise wird der Compiler einen hinzufügen, wenn er C in Assembly übersetzt.
Oder
2) Legen Sie das Etikett in einen Montageabschnitt. Dies verhindert, dass der Compiler das '_' hinzufügt.
Oder
3) Kommentieren Sie die Assembly, kompilieren Sie und suchen Sie in der Listendatei (* .lst) nach dem Namen des Labels.
Hat die Turbo C ++ - Umgebung eine Möglichkeit, Optionen für TASM festzulegen (ich weiß, dass einige der Borland-IDEs dies taten)?
Wenn ja, sehen Sie, ob die Option für "Maximale Anzahl an Durchgänge (/ m)" auf 2 oder mehr Werte gesetzt wird (es könnte standardmäßig 1 Durchlauf sein).
Wenn Sie einen langen Labelnamen verwenden, der ein Problem darstellen könnte, wurde die Standardeinstellung für mindestens eine IDE auf 12 festgelegt. Ändern Sie die Option "Maximale Symbollänge (/ mv)".
Diese Information basiert auf Borlands RAD Studio IDE:
Ein paar weitere Dinge (Schüsse im Dunkeln) zu versuchen:
Sehen Sie, ob die folgende Montageanleitung hilft:
%Vor%Die meisten Compiler können eine Assembly-Liste des generierten Codes erstellen (nicht sicher, ob Turbo C ++ dies kann, da Codegear / Embarcadero es als kostenlosen, nicht professionellen Compiler positioniert).
Versuchen Sie, eine Liste mit C-Code zu erstellen, der eine Beschriftung verwendet (z. B. goto
target), mit einer Inline-Assembly in derselben Funktion, aber versuchen Sie nicht, über die Baugruppe auf die Beschriftung zuzugreifen. So können Sie einen Compiler ohne Fehler und eine Assembly-Liste erhalten. Etwas wie:
Sehen Sie sich die Assembly-Liste an und prüfen Sie, ob die generierte Assembly den Labelnamen auf eine Weise darstellt, die Sie möglicherweise in der Inline-Assembly replizieren können.
Soweit ich mich erinnere, können Sie kein externes (C ++) Label in Ihrer Inline-Assembly verwenden, obwohl Sie TASM-artige Labels im asm-Block haben können, die von den Assembly-Anweisungen selbst referenziert werden können. Ich denke, ich würde ein Flag und eine Post-Assembler-Switch-Anweisung verwenden, um Branching zu behandeln. Zum Beispiel:
%Vor%Ich weiß nicht speziell über Ihren Compiler / Assembler, aber ein Trick, den ich ziemlich oft benutzt habe, besteht darin, den nächsten Ort aufzurufen und dann den Stack in Ihr Register zu stecken. Stellen Sie sicher, dass der Anruf, den Sie tätigen, nur die Absenderadresse drückt.
Ich denke, das Problem, auf das Sie stoßen, ist, dass ein Label im __asm
-Block und das Label im C ++ - Code zwei völlig verschiedene Dinge sind. Ich würde nicht erwarten, dass Sie ein C ++ - Label auf diese Weise von Inline-Assembly referenzieren können, aber ich muss sagen, es ist sehr lange her, seit ich Turbo C ++ verwendet habe.
Haben Sie die lea
Anweisung anstelle von mov
versucht?
Nur Raten, da ich Inline-Assembler nicht mit irgendeinem C / ++ - Compiler verwendet habe ...
%Vor%Ich kenne die genaue Syntax von TASM nicht.