This code boils down to,
rax = min(rdx,rax)
rdx = sub(rdx,rax) ; store the difference in rdx
That is essentially,
rdx - 0
(if rdx
is the min)
rdx - (rdx-rax)
(if rax
is the min)
The sbb
and and
here just move into rcx
either
What determines what gets moved into rcx
? That's determined by the result of the sbb
. The sbb
is doing reg - reg - CF
. So you're either AND
ing against all 1
s or all 0
s.
This is how I reasoned about it
# CF=0; rdx > rax
if ( rdx > rax ) {
rdx -= rax
rcx = 0 ; all bits off
; AND 0 (rcx) with anything (in rdx) is nop here.
; ADDing 0 (rcx) to rax is a nop
}
# CF=1; rax > rdx
else {
rdx -= rax
rcx = -1 ; all bits on
rcx = rdx ; code is rcx &= rdx
; remember -1 & x == x
rax += rcx
}
Note regardless of the carry flag, this code will store the difference in rdx