条件付きでゼロをレジスタに移動しますか?

Dec 01 2020

アセンブリ内のレジスタにゼロを条件付きで移動する方法はありますか?私がやろうとしている

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

しかし、コンパイラは、最初のオペランドが即値定数であるという事実のために、「cmovgのオペランドタイプの不一致」について不平を言っています。movへの条件付きジャンプについて考えましたが、他にもっと良いオペコードがあるかどうかはわかりません。別のレジスタを使い果たすことなく、このレジスタを条件付きでゼロにするにはどうすればよいですか?

回答

dannyadam Dec 01 2020 at 03:36

cmovgq命令は即値オペランドを受け入れないため、別のレジスタを使用しないアプローチでは、スタックにゼロ値を追加し、即値を使用する代わりに対応するアドレスを使用してから、スタックポインタを復元することができます。

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

あるいは、ゼロをスタックにプッシュしてからスタックポインタを復元するのではなく、ゼロ値をメモリの他の場所に格納することもできます。

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

  .section .rodata
zero:
  .quad 0

を使用するのcmovgqではなく、条件付きジャンプは別のレジスタを使用しない代替アプローチであり、同じ動作になります(つまり、rcx条件付きで0に設定されます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:
  ...