Bedingte Null ins Register verschieben?

Dec 01 2020

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

dannyadam Dec 01 2020 at 03:36

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:
  ...