Déplacement conditionnel de zéro dans le registre?
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
Étant donné que l' cmovgq
instruction 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, rcx
mis 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:
...