Why the status flags in AVR are on after one's-complementing a zeroed register?

208 views Asked by At

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.

1

There are 1 answers

0
Peter Cordes 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 for sub that it sets C if sub Rd, Rr has Rd >= 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 its sub / sbc to work.

So I think com sets flags exactly sub 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 because 0xff - 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.