I have a code in assembly and I have to find out why the status flags are on
One of the codes is
LDI R16, 0
COM R16
the result was 0xFF
But I don’t understand why the S
and C
flags were on.
I have a code in assembly and I have to find out why the status flags are on
One of the codes is
LDI R16, 0
COM R16
the result was 0xFF
But I don’t understand why the S
and C
flags were on.
COM isn't "complete", it's "one's complement" (bitwise inversion). Read the manual which explains how each instruction sets flags. http://atmel-studio-doc.s3-website-us-east-1.amazonaws.com/webhelp/GUID-0B644D8F-67E7-49E6-82C9-1B2B9ABE6A0D-en-US-1/GUID-7066B778-FBFB-4B81-A2B1-5E04395FB24D.html
It describes the "operation" as
Rd ← $FF - Rd
- I guess AVR's Carry flag is inverted on subtract (a not-borrow) like ARM? Yes, we can see from the docs forsub
that it setsC
ifsub Rd, Rr
hasRd >= Rr
, if I'm reading that right? Hmm, there's stuff about "absolute value" that seems odd, not 100% sure it's equivalent to what ARM does, although I'd guess so for itssub
/sbc
to work.So I think
com
sets flags exactlysub
from$ff
, which is probably easy for an AVR to implement internally.The documentation for how
com
actually sets status flags specifically says it always sets C to 1. So of course it always does that. The interesting part is that that's probably because0xff - anything
can't have unsigned overflow and wrap around producing a borrow.The N flag is set according to the result, V (signed overflow) is always cleared, and S = N^V is thus set according to the high bit of the register which in your case became 1.