Es gibt keinen x86-Befehl zu „drucken“ ein Wert. Die Anzeige der Ausgabe erfordert eine betriebssystemspezifische Schnittstelle. Bei der "klassischen" x86-Programmierung würden Sie einen BIOS-Aufruf durchführen, um die Ausgabe auf dem Bildschirm zu generieren. In modernen Protected-Mode-Betriebssystemen wird dies nicht mehr funktionieren. Stattdessen müssen Sie eine OS-API-Funktion aufrufen, um die Ausgabe anzuzeigen, z. B. . an ein Konsolenfenster, das mit Ihrem Prozess verknüpft ist.
Die einfachste und universellste Methode zum Aufrufen dieser OS-API besteht darin, das Assembly-Programm mit der C-Standardbibliothek zu verknüpfen, sodass Sie die printf
(und ähnliche) Funktion (en) aufrufen können. Dies erfordert wenig mehr als eine CALL
-Anweisung, die die Steuerung an die printf
-Funktion überträgt, sie ausführt und die Steuerung an die folgende Anweisung in Ihrem Code zurückgibt.
Es gibt jedoch noch eine zusätzliche Komplikation: Sie müssen die entsprechende Aufrufkonvention für Ihre Plattform und für die Standardbibliotheksfunktionen befolgen. Ihre Frage bietet keine Hinweise darauf, ob Sie Windows, Linux oder etwas anderes verwenden. Glücklicherweise sind detaillierte Informationen über x86-Aufrufkonventionen im x86-Tag-Wiki verfügbar, erreichbar unter here. Im Allgemeinen übergeben 32-Bit-Aufrufkonventionen Parameter auf dem Stapel von rechts nach links. Und die C-Standardbibliotheksfunktionen sind praktisch immer aufruferbereinigend (selbst unter Windows, wo sonst eine Aufräumkonvention üblich ist), so dass Sie nach dem Aufruf dafür verantwortlich sind, den Stapel zu bereinigen.
So, wie eine Demonstration hier ist, wie Sie printf
nennen könnten die 32-Bit-Integer im EAX
Register gespeichert drucken:
push eax ; push 32-bit integer value from EAX onto stack
push OFFSET strFormat ; push pointer to format string onto stack
call printf
add esp, 8 ; clean up stack
strFormat
muß in Ihrem ausführbaren DATA
Abschnitt gespeichert ein String sein. Die Formatzeichenfolgen sind die gleichen wie für C, da es genau die gleiche Funktion ist. In diesem Fall würde dann ein Zeiger auf eine Zeichenfolge mit "%d"
gesetzt werden.
Die Dinge sind sehr ähnlich, um einen 64-Bit-Wert zu drucken, außer dass Ihre Formatzeichenfolge "%lld"
ist (verwenden Sie den long long
-Typ in C, der 64 Bit auf x86-32 ist). Sie müssen den Regeln der Aufrufkonvention folgen, um einen 64-Bit-Integer-Parameter an eine Funktion zu übergeben. Es ist wahrscheinlich, dass dies einfach dazu führt, beide 32-Bit-Hälften auf den Stapel zu schieben. Unter der Annahme, dass der 64-Bit-Wert kanonisch in EDX:EAX
gespeichert wird, würde der Code wie folgt aussehen:
push edx ; push upper 32 bits of 64-bit integer value onto stack
push eax ; push lower 32 bits of 64-bit integer value onto stack
push OFFSET strFormat64 ; push pointer to format string onto stack
call printf
add esp, 12 ; clean up stack
Wenn der Wert im Speicher vorhanden ist, dann können Sie Code verwenden, wie Sie in der Frage zeigen:
lea edx, DWORD PTR [value]
mov eax, DWORD PTR [edx]
mov edx, DWORD PTR [edx+4]
push edx
push eax
push OFFSET strFormat64
call printf
add esp, 12
Beachten Sie, dass wenn Sie dies als ein Makro implementieren, es Clobber-Register wird. Stellen Sie sicher, dass dies entweder eindeutig dokumentiert ist oder dass Sie die Register innerhalb des Makros speichern und wiederherstellen. Andernfalls werden Sie mit schwer zu debuggenden Problemen konfrontiert, wenn Sie dies in Ihrem Code verwenden! Abhängig von Ihrer Aufrufkonvention müssen Sie möglicherweise sicherstellen, dass der Stapel korrekt ausgerichtet ist. Dies kann in einem Makro schwierig und generisch schwierig sein. MASM verfügt über eine INVOKE
Pseudo-Anweisung, die automatisch eine Funktion für Sie aufrufen kann.Es könnte sich lohnen zu überprüfen, ob Ihr Assembler eine ähnliche Funktion hat.
Ausdrucken - wie? Dezimal, hexadezimal, binär? Können Sie herausfinden, wie Sie einen einzelnen Byte-Wert in dem Notationssystem Ihrer Wahl drucken können? – usr2564301
Wenn dezimal, können Sie hier nach einer Routine suchen: http://StackOverflow.com/a/41086442/4271923 (übrigens, setzen Sie nicht ganze Routine in Makro, wird es im Maschinencode für jede Verwendung = = wiederholen große binäre => langsam. Verwenden Sie lieber 'call' und Unterprogramme.) – Ped7g
Ich fand einen sehr einfachen Weg: push ebx; untere 32 Bits push eax; obere 32 Bits Push-Offset-Format Aufruf printf add esp, 12; Löschen Sie den Stapel wo Format ist Format DB "% lld", 0 – Crisan