Warunkowe zerowanie do rejestru?
Czy istnieje sposób warunkowego przeniesienia zera do rejestru w asemblerze? Próbuję to zrobić
cmpb %r9b, %r8b #compare r9 and r8
cmovgq $0, %rcx #If r8>r9, move zero to rcx
Jednak kompilator skarży się na „niezgodność typu argumentu dla cmovg” z powodu faktu, że pierwszy operand jest natychmiastową stałą. Myślałem o warunkowym skoku do mov, ale nie jestem pewien, czy są inne kody, które mogłyby być lepsze. Jak mogę warunkowo wyzerować ten rejestr bez zjadania innego rejestru?
Odpowiedzi
Ponieważ cmovgq
instrukcja nie akceptuje natychmiastowego operandu wartości, podejście, które nie używałoby innego rejestru, mogłoby polegać na dodaniu wartości zerowej do stosu, użyciu odpowiadającego mu adresu zamiast używania wartości bezpośredniej, a następnie przywróceniu wskaźnika stosu.
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
Alternatywnie, zamiast wpychać zero do stosu, a następnie przywracać wskaźnik stosu, wartość zerowa może być przechowywana w innym miejscu w pamięci.
cmpb %r9b, %r8b # compare r9b and r8b
cmovgq zero, %rcx # if r8b > r9b, move zero to rcx
...
.section .rodata
zero:
.quad 0
Zamiast używania cmovgq
, skok warunkowy jest alternatywnym podejściem, które nie użyłoby innego rejestru i spowodowałoby to samo zachowanie (tj. rcx
Warunkowo ustawione na 0, jeśli 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:
...