Mover zero condicional para o registro?

Dec 01 2020

Existe uma maneira de mover um zero condicional para um registro na montagem? Estou tentando fazer

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

Mas o compilador está reclamando de "incompatibilidade de tipo de operando para cmovg" devido ao fato de que o primeiro operando é uma constante imediata. Eu pensei em pular condicional para um mov, mas não tenho certeza se há outros opcodes que podem ser melhores. Como posso zerar condicionalmente esse registro sem consumir outro registro?

Respostas

dannyadam Dec 01 2020 at 03:36

Como a cmovgqinstrução não aceita um operando de valor imediato, uma abordagem que não usaria outro registrador seria adicionar o valor zero à pilha, usar seu endereço correspondente em vez de usar um valor imediato e restaurar o ponteiro da pilha.

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

Alternativamente, em vez de empurrar zero para a pilha e restaurar o ponteiro da pilha, o valor zero pode ser armazenado em outro lugar na memória.

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

  .section .rodata
zero:
  .quad 0

Em vez de usar cmovgq, um salto condicional é uma abordagem alternativa que não usaria outro registro e resultaria no mesmo comportamento (ou seja, rcxdefinido condicionalmente como 0 se 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:
  ...