Bedingte Null ins Register verschieben?
Gibt es eine Möglichkeit, eine Null in ein Register in der Baugruppe zu verschieben? Ich versuche es zu tun
cmpb %r9b, %r8b #compare r9 and r8
cmovgq $0, %rcx #If r8>r9, move zero to rcx
Der Compiler beschwert sich jedoch über "Nichtübereinstimmung des Operandentyps für cmovg", da der erste Operand eine unmittelbare Konstante ist. Ich habe über das bedingte Springen zu einem Film nachgedacht, bin mir aber nicht sicher, ob es andere Opcodes gibt, die möglicherweise besser sind. Wie kann ich dieses Register bedingt auf Null setzen, ohne ein anderes Register zu verschlingen?
Antworten
Da der cmovgqBefehl keinen Sofortwertoperanden akzeptiert, könnte ein Ansatz, der kein anderes Register verwenden würde, darin bestehen, den Nullwert zum Stapel hinzuzufügen, seine entsprechende Adresse anstelle eines Sofortwerts zu verwenden und dann den Stapelzeiger wiederherzustellen.
pushq $0 # push 0 onto the stack cmpb %r9b, %r8b # compare r9b and r8b cmovgq (%rsp), %rcx # if r8b > r9b, move zero to rcx addq $8, %rsp # restore stack pointer
Alternativ könnte der Nullwert an anderer Stelle im Speicher gespeichert werden, anstatt Null auf den Stapel zu drücken und dann den Stapelzeiger wiederherzustellen.
cmpb %r9b, %r8b # compare r9b and r8b
cmovgq zero, %rcx # if r8b > r9b, move zero to rcx
...
.section .rodata
zero:
.quad 0
Anstatt zu verwenden cmovgq, ist ein bedingter Sprung ein alternativer Ansatz, der kein anderes Register verwenden würde und zu demselben Verhalten führen würde (dh rcxbedingt auf 0 gesetzt, wenn r8b > r9b).
cmpb %r9b, %r8b # compare r9 and r8
jle destination # if r8b <= r9b, skip the next line
movq $0, %rcx # if r8b > r9b, move zero to rcx
destination:
...