Déplacement conditionnel de zéro dans le registre?

Dec 01 2020

Existe-t-il un moyen de déplacer conditionnellement un zéro dans un registre dans l'assembly? J'essaye de faire

cmpb %r9b, %r8b #compare r9 and r8
cmovgq $0, %rcx #If r8>r9, move zero to rcx

Mais le compilateur se plaint d'une "incompatibilité de type d'opérande pour cmovg" en raison du fait que le premier opérande est une constante immédiate. J'ai pensé au saut conditionnel vers un mov, mais je ne sais pas s'il existe d'autres opcodes qui pourraient être meilleurs. Comment puis-je mettre à zéro conditionnellement ce registre sans en manger un autre?

Réponses

dannyadam Dec 01 2020 at 03:36

Étant donné que l' cmovgqinstruction n'accepte pas d'opérande de valeur immédiate, une approche qui n'utiliserait pas un autre registre pourrait consister à ajouter la valeur zéro à la pile, à utiliser son adresse correspondante au lieu d'utiliser une valeur immédiate, puis à restaurer le pointeur de pile.

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

Sinon, plutôt que de pousser zéro dans la pile puis de restaurer le pointeur de pile, la valeur zéro pourrait être stockée ailleurs dans la mémoire.

  cmpb    %r9b, %r8b  # compare r9b and r8b
  cmovgq  zero, %rcx  # if r8b > r9b, move zero to rcx
  ...

  .section .rodata
zero:
  .quad 0

Plutôt que d'utiliser cmovgq, un saut conditionnel est une approche alternative qui n'utiliserait pas un autre registre, et entraînerait le même comportement (c'est-à-dire, rcxmis conditionnellement à 0 si 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:
  ...