gas - 'Wrong' usage of carry flag in ARM subtract instructions? -
the arm subtraction instructions carry (sbc
, rsc
) interpret carry flag (c) as:
- 0 means borrow
- 1 means no borrow
why carry flag c
inversed make arithmetic?
sbc r0, r1, r2 @ r0 = r1 - r2 - !c
we know grade school that
a = b - c = b + (-c)
and elementary programming classes negate number in twos complement invert number , add 1
a = b + (~c) + 1
and works out because when feed adder logic our values invert second operand , invert carry in. (there no subtract logic use adder subtraction)
so processor implementations choose invert carry out. inverting stuff subtract, , raw carry out of msbit on normal subtract (without borrow) 1, when there borrow carry out 0, inverting carry out can call "borrow" instead of carry (or instead of /borrow or !borrow or borrow_n)
which ever way it, if have subtract borrow, need either invert or not invert carry in depending design choices carry out on subtract (normal without borrow).
so subtraction is
a = b + (~c) + 1
and when cascade subtraction (sbc) if there no borrow
a = b + (~c) + 1
but if there borrow next level needs have 1 removed sbc becomes
a = b + (~c)
the carry in 0 in case. adder logic perspective when subtract borrow naturally have invert second operand, carry in 0 if have borrow , carry in 1 if dont.
the arm docs on sbc say
rd = rd - rm - not(c flag)
so if need take 1 away due prior borrow c needed 0 else c 1 going in.
the subtractions say
c flag = not borrowfrom(operation)
so if need borrow borrow true c flag not true or 0. if dont need borrow, borrow false 0, , not borrow 1. matches up, if needed borrow going sbc c needs 0.
so arm not appear modify carry out adder. , not need invert carry in on sbc.
Comments
Post a Comment