Aneesh Dogra
Aneesh Dogra

Reputation: 740

Use of carry flag for SBB RCX,RCX after subtraction

I am reading a book: [xchg rax, rax]. The following is the 0x03 snippet of the book and I can't make sense out of this one.

sub      rdx,rax
sbb      rcx,rcx
and      rcx,rdx
add      rax,rcx

I have been working on this since a week now (couple of minutes everyday). I have studied about some things trying to solve it: signed representation of numbers, how subtraction works, role of CF after a subtraction. According to this answer and the list given here. I don't see the point of checking CF after a subtraction, except in the cases of maybe overflows.

In what situations is checking the carry flag useful after a subtraction?

Upvotes: 3

Views: 622

Answers (1)

Jester
Jester

Reputation: 58792

Actually that code is a clever branchless way to do rax = min(rax, rdx).

sub rdx, rax ; rdx = rdx - rax; CF set if rdx < rax
sbb rcx, rcx ; rcx = all 1 bits if CF was set, 0 otherwise
and rcx, rdx ; rcx = rdx - rax if CF was set, 0 otherwise
add rax, rcx ; rax = rax + (rdx - rax) = rdx if CF was set, unchanged otherwise

A more readable branching version is:

cmp rdx, rax
jnc done ; if rdx - rax produced no carry, rax is smaller or equal
mov rax, rdx ; otherwise rdx is the smaller one
done:

It's still just using CF for overflow checking.

Upvotes: 5

Related Questions