I was wondering why the Atmel RISC doesn't have a "clear all" instruction for the status register and only individual flag clear instructors like CLN and CLS. It is a safety thing to force the programmer to explicitly clear each bit individually and avoid carelessness?
[edit] asking because i'm examining the effect of various instructions on the status register for a class and i was looking for an instruction to reset SREG entirely when i realized such instruction doesn't exist
It is a safety thing to force the programmer to explicitly clear each bit individually and avoid carelessness?
No, it's just not worth providing a special instruction just for this. Note that SREG includes both the Interrupt enable/disable bit and the condition-codes, and I imagine it's pretty rare you'd ever need to clear both at once.
(Also the Transfer flag which is left unmodified even by instructions like cmp
and sub
, only used for bst
/ bld
and the corresponding branches).
You don't have to run clz
/ cln
/ ... in sequence, you need at most 2 instructions. Since this specific operation isn't common or usually useful, it's not something that most ISAs would bother to provide an instruction for.
Covering just the condition codes (not I and T), you can do it in 2 instructions with
ldi r16, 1
/ subi r16, 0
: no Carry, no Overflow, no half-Carry, result is non-Zero, result is non-Negative. subi reg,0
works to clear all condition codes with any non-negative register value, so you can often avoid an extra ldi
.
cp r16,r16 ; clears all condition codes except Z=1. (I and T unmodified)
clz ; Z=0
This 2nd way does it without modifying any other registers. (andi
/or
leave some condition codes unset, but instructions like add/sub/compare (cp
) write them all.) Any number minus itself is 0, with no carry, overflow or anything. cp
is like a sub
that leaves its destination unmodified.
Some ISAs provide a way to copy their flags register (if they have one) to/from a general-purpose register, but AVR doesn't need to cover every corner case because its registers are memory-mapped, including SREG. It's a RISC CPU with better uses for limited opcode space in its 16-bit fixed-width instruction format.
In Data space, SREG's address is 0x5F
. In I/O space, it's 0x3F
(wikipedia). out
is shorter than sts
/ lds
, and more convenient than st
/ld
with an addressing mode involving an index register (X,Y, or Z).
SREG
, including I and T, disabling interrupts ; R1 = 0 is normally left 0 at all times, one LDI at startup
out $3F, r1 ; SREG = 0