Post by Sebastian BiallasPost by Jan Brunsmov eax,$12345678
mov ax, $5678
mov al, $78
-> eax = $12345678
Das gilt auch weiterhin. Allerdings gilt danach (rax&0xffffffff00000000)==0.
Naja, interessiert mich momentan nicht hinreichend, um das nachzuschlagen.
Jedenfalls: Ziemlich inkonsequent sieht das aus.
Post by Sebastian BiallasDas ist aber auch sinnvoll so. Obiges Verhalten war vor 20 Jahren
vielleicht noch verständlich, ist aber für heutige Prozessoren sehr
schlecht, weil man mit den partial register stalls umgehen muss.
Also ich kann nun nicht gerade behaupten, über die pipelinetechnsichen
Hintergründe bzgl. partieller Register genauestens informiert zu sein.
Klingt für mich eigentlich eher nach Integrationsdichte, als nach
echten Engpässen.
Post by Sebastian BiallasBei dem "mov al, $78" muss der Prozessor entweder auf den Wert von rax
warten, bis er den Befehl zuende ausführen kann, oder er zerteilt das
Register und muss es später u.U. wieder kompliziert zusammenführen. Ein
"mov eax, $78" hingegen kann er unabhängig von dem vorigen Wert von rax
ausführen.
Der Prozessor muss auf rax warten? Wo ist denn rax implementiert?
Du meinst wahrscheinlich einfach irgendeine zentrale Verarbeitungseinheit
in der CPU. Dazu ist einfach mal festzustellen, daß es neben schematischen
Trennung von Befehlausführung und Registersatz auch völlig andere
Implementationen denkbar sind. Bspw. könnte man für jedes Register
eine eigene Ausführungseinheit vorsehen, um dann nur noch Datentransfers
zwischen Registern bzw. externem Speicher zentralisiert organisieren zu
müssen. In Anbetracht der "aktuellen" Problematik weiterhin schnell
steigende(r) Integrationsumfang/dichte bei geringem Taktratenzuwachs
vielleicht nichtmal eine völlig absurde Vorgehensweise.
Post by Sebastian BiallasSchau Dir mal Code vom einem aktuellen Compiler an, der mit Bytes
handtiert (z.B. Stringverarbeitung). Der ist voll von scheinbar
unnötigen movzx/movsx. Das macht man halt, um dem Prozessor Arbeit
abzunehmen.
Also Du meinst den Zusammenhang, daß obwohl nur bspw. vereinzelte
Bytes zu verarbeiten sind (von denen mehrere in einem Register
gespeichert werden könnten), in der Praxis trotzdem regelmässig nur
eine Dateneinheit pro Register verwendet wird, und dabei denn auch
unnötig häufig die nicht verwendeten Anteile explizit überschrieben
werden?
Das hat vielleicht verschiedene Ursachen, aber einer davon ist
sicherlich memory alignment. Wenn es dagegen darum geht, bspw.
den Befehl "mov al,bl" CPU-optimiert zu schreiben, kam da
bislang regelmässig sowas wie "mov eax,ebx" heraus, wenn die
oberen Anteile von ebx eh' trivial sind, obwohl die Formulierung
"movzx eax,bl" sicherlich einfacher ist.
Gruss
Jan Bruns