Wenn Sie nur 32-Bit-Register benötigen, können Sie sicher mit ihnen arbeiten, dies ist OK unter 64-Bit. Wenn Sie aber nur 16-Bit- oder 8-Bit-Register benötigen, sollten Sie diese vermeiden oder immer movzx/movsx verwenden, um die restlichen Bits zu löschen. Es ist allgemein bekannt, dass unter x86-64 die Verwendung von 32-Bit-Operanden die höheren Bits der 64-Bit-Register löscht. Der Hauptzweck dieses Verfahrens ist die Vermeidung falscher Abhängigkeits-Ketten.
Bitte beachten Sie den entsprechenden Abschnitt - 3.4.1.1 - des Dokuments Intel® 64- und IA-32-Architekturen Handbuch für Softwareentwickler Band 1 :
32-Bit-Operanden erzeugen ein 32-Bit-Ergebnis, das im Mehrzweck-Zielregister auf ein 64-Bit-Ergebnis erweitert wird
Die Unterbrechung von Abhängigkeitsketten ermöglicht die parallele Ausführung von Anweisungen in zufälliger Reihenfolge durch den Out-of-Order-Algorithmus seit dem Pentium Pro im Jahr 1995 intern in CPUs implementiert.
Ein Zitat aus dem Handbuch zur Optimierung von Intel® 64- und IA-32-Architekturen Abschnitt 3.5.1.8:
Bei Codesequenzen, die partielle Register ändern, kann es zu Verzögerungen in der Abhängigkeitskette kommen, die jedoch durch die Verwendung von Idiomen zur Aufhebung von Abhängigkeiten vermieden werden können. Bei Prozessoren, die auf der Intel Core-Mikroarchitektur basieren, kann eine Reihe von Anweisungen dazu beitragen, die Ausführungsabhängigkeit aufzulösen, wenn die Software diese Anweisungen verwendet, um den Registerinhalt auf Null zu setzen. Unterbrechen Sie Abhängigkeiten von Teilen von Registern zwischen Befehlen, indem Sie mit 32-Bit-Registern anstelle von Teilregistern arbeiten. Bei Verschiebungen kann dies mit 32-Bit-Verschiebungen oder durch Verwendung von MOVZX erreicht werden.
Assembler/Compiler-Codierung Regel 37. (M Auswirkung, MH Allgemeinheit) : Unterbrechen Sie die Abhängigkeit von Teilen von Registern zwischen Befehlen, indem Sie auf 32-Bit-Registern statt auf Teilregistern arbeiten. Bei Verschiebungen kann dies mit 32-Bit-Verschiebungen oder durch Verwendung von MOVZX erreicht werden.
MOVZX und MOV mit 32-Bit-Operanden für x64 sind gleichwertig - sie alle unterbrechen Abhängigkeitsketten.
Aus diesem Grund wird Ihr Code schneller ausgeführt, wenn Sie bei der Verwendung kleinerer Register immer versuchen, die höchsten Bits der größeren Register zu löschen. Wenn die Bits immer gelöscht sind, gibt es keine Abhängigkeiten vom vorherigen Wert des Registers, die CPU kann die Register intern umbenennen.
Umbenennung von Registern ist eine Technik, die intern von einer CPU verwendet wird, um die falschen Datenabhängigkeiten zu beseitigen, die durch die Wiederverwendung von Registern durch aufeinanderfolgende Anweisungen entstehen, zwischen denen keine echten Datenabhängigkeiten bestehen.
1 Stimmen
In Linux (und wahrscheinlich auch in allen anderen Systemen) sind die Parameter für einen Syscall 32-Bit breit, so dass Sie EDI und EDX verwenden sollten. win.tue.nl/~aeb/linux/lk/lk-4.html#ss4.3
0 Stimmen
Was ist mit rax, sollte das auch in eax geändert werden? Ich habe versucht, diese 3 zu ändern und es funktioniert, aber was ich wissen möchte, ist, warum ich dies tun sollte und was ist der Vorteil.
0 Stimmen
Im Fall dieses Programms besteht der einzige nennenswerte Unterschied darin, dass die literalen Werte (4, 1, 0 usw.) doppelt so groß sind, wenn sie 64-Bit sind, so dass Ihr Programm ein paar Bytes größer ist und theoretisch länger dauern könnte, um von der Festplatte/dem Speicher in die CPU zu laden.
0 Stimmen
Es gibt also keinen Grund, die vollen 64 Bit zu verwenden, wenn es nicht nötig ist, oder? (Ich weiß, dass es auch keinen Grund gibt, Assembler von Hand zu codieren, aber ich will nur sichergehen )
0 Stimmen
@MattyK:
mov r64, sign-extended-imm32
beträgt 7 Bytes, gegenüber 5 Bytes beimov r32, imm32
. In GAS können Sie Folgendes verwendenmovabs
anzufordernmov r64, imm64
aber NASM/YASM wählen diese Kodierung nur auf der Grundlage der Größe der Konstante. (Und in der Tat optimiert NASM kleine Konstanten aufmov r32, imm32
wenn Sie das Ziel alsrdi
. Ich bin mir nicht sicher, was die Symboladressen angeht; es könnte sein, dass sie alsimm64
für den Fall, dass Sie nicht das "kleine" Codemodell verwenden und Symbole mit Adressen über 32 Bit haben. Es wird nicht optimiertmov rdi,0
axor edi,edi
allerdings wegen der Nebenwirkung auf Flaggen).0 Stimmen
Verwandt: Die Vorteile der Verwendung von 32-Bit-Registern/Befehlen in x86-64 . Bei der Aufnahme von Konstanten in Register wird nur die 32-Bit-Null-Erweiterung implizit auf 64-Bit erweitert. Für die Aufnahme von Adressen in Register, 10-Byte
mov r64, imm64
funktioniert, ist aber schrecklich; verwenden Sie RIP-relativlea rsi, [rel msg]
. MacOS verwendet zwangsläufig 64-Bit-Adressen, so dass Sie nicht optimieren können mitmov esi, msg
wie unter Linux.