wake-up-neo.com

Wie speichere ich die Register auf x86_64 für eine Interrupt-Serviceroutine?

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.

23
Mr. Shickadance

Lernen Sie aus vorhandenem Code, der solche Aufgaben ausführt. Zum Beispiel:

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.

7
FrankH.

pusha ist im 64-Bit-Modus nicht gültig, da es redundant ist. Es ist genau das Richtige, jedes Register einzeln zu verschieben.

5
user200783

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

1
baz