gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

ASM > Set carry?

#168661 - Dwedit - Wed May 13, 2009 10:05 pm

What's the easiest way to set the carry flag in one instruction?
_________________
"We are merely sprites that dance at the beck and call of our button pressing overlord."

#168662 - Ruben - Wed May 13, 2009 11:30 pm

My guess is to compare/subtract a number > 0 to 0

#168668 - Dwedit - Thu May 14, 2009 9:36 am

Ah yes, the curse of knowing the Z80, where the carry flag is opposite of the ARM when doing subtraction.
In other words, "CMP pc,#0" sets the carry flag in all practical uses.
_________________
"We are merely sprites that dance at the beck and call of our button pressing overlord."

#168675 - eKid - Fri May 15, 2009 7:56 am

Or any register... 0 minus 0 should set carry too I believe.

#168682 - Miked0801 - Fri May 15, 2009 4:05 pm

That makes no sense to me. -0 shifts nothing to carry. Are you looking to do it non destructively? If so, not sure. Otherwise, move r0,#1,lsr 1 would probably do it.

#168683 - Ruben - Fri May 15, 2009 4:11 pm

Well, I'm not sure either... I got that result after testing with changing instructions in no$

#168694 - eKid - Fri May 15, 2009 9:37 pm

Think of it as "register + 2^32 - 0". So cmp rr, #0 or subs rr, #0 should both set carry without killing the registers.

#168698 - Miked0801 - Sat May 16, 2009 1:42 am

But setting carry on a 0 subtract with destroy sbc type commands.

subs ro,r1,0
sbcs r0,r2,r3

or whatever. A zero subtract would throw off multiple register subtracts.

#168704 - eKid - Sat May 16, 2009 3:03 am

Eh? :|

If you're going to be setting the carry then it isn't going to be in the middle of a multiple register arithmetic operation thing.

#168705 - Cearn - Sat May 16, 2009 10:00 am

Miked0801 wrote:
But setting carry on a 0 subtract with destroy sbc type commands.

subs ro,r1,0
sbcs r0,r2,r3

or whatever. A zero subtract would throw off multiple register subtracts.
It won't. SBC is actually Rn-Op2+Carry-1, rather than just +Carry. Because of this, it'll work out.

Code:
Rn : (r2<<32) + r0
Rs : (r3<<32) + r1
Rn -= Rs

@ Examples

@ Rn - 0
subs    r0, r0, #0   @ Subtract low. Sets Carry. C=1
sbc     r2, r2, #0   @ Substract hi. Uses +C-1 = +0

@ 0 - 1. R0= r2= r3= 0. r1= 1
subs    r0, r0, r1   @ Effectively does 0x1:0000:0000 - 1 = 0x0:FFFF:FFFF. C=0
sbc     r2, r2, r3   @ 0-0 + C-1 = 0 + 0-1 = -1 = 0xFFFF:FFFF

Also note that the -CS condition means 'unsigned higher or same'. This effectively corresponds to what eKid said: Rd = Rn+2³² - Rs. Something like `cmp Rx, Rx' should work as well.

#168728 - Miked0801 - Sun May 17, 2009 8:05 pm

Fair enough. Thanks for the explanation. I cut my teeth on the DMG/GBC where carry ops were very common.