Ich schaue mir einen alten Code aus einem Schulprojekt an und stieß beim Versuch, ihn auf meinem Laptop zu kompilieren, auf einige Probleme. Es wurde ursprünglich für eine alte 32-Bit-Version von gcc geschrieben. Auf jeden Fall habe ich versucht, einen Teil der Assembly in 64-Bit-kompatiblen Code umzuwandeln und ein paar Fehler zu beheben.
Hier ist der Originalcode:
pusha
pushl %ds
pushl %es
pushl %fs
pushl %gs
pushl %ss
pusha
ist im 64-Bit-Modus nicht gültig. Also, was wäre der richtige Weg, um dies in x86_64-Assembly im 64-Bit-Modus zu tun?
Es muss einen Grund geben, warum pusha
im 64-Bit-Modus nicht gültig ist, daher habe ich das Gefühl, dass es keine gute Idee ist, alle Register manuell zu drücken.
Lernen Sie aus vorhandenem Code, der solche Aufgaben ausführt. Zum Beispiel:
SAVE_ARGS_IRQ
): entry_64.SINTR_Push
): privregs.hIDT_VEC
): exception.S (ähnlich ist vector.S in NetBSD)Tatsächlich ist das "manuelle Pushen" der Regs der einzige Weg auf AMD64, da PUSHA
dort nicht existiert. AMD64 ist in diesem Punkt nicht einzigartig - die meisten Nicht-x86-CPUs erfordern auch irgendwann Register-für-Register-Speichern/Wiederherstellen.
Wenn Sie jedoch den Quellcode, auf den verwiesen wird, genau untersuchen, werden Sie feststellen, dass nicht alle Interrupt-Handler den gesamten Registersatz speichern/wiederherstellen müssen, sodass Optimierungsbedarf besteht.
pusha
ist im 64-Bit-Modus nicht gültig, da es redundant ist. Es ist genau das Richtige, jedes Register einzeln zu verschieben.
Hallo, es ist vielleicht nicht der richtige Weg, es zu tun, aber man kann Makros wie erstellen
.macro pushaq
Push %rax
Push %rcx
Push %rdx
Push %rbx
Push %rbp
Push %rsi
Push %rdi
.endm # pushaq
und
.macro popaq
pop %rdi
pop %rsi
pop %rbp
pop %rbx
pop %rdx
pop %rcx
pop %rax
.endm # popaq
und schließlich die anderen r8-15-Register hinzufügen, wenn man muss