Search code examples
assemblyavrstatus-register

Why isn't there a clear SREG RISC instruction?


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


Solution

  • 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).

    To actually zero the whole 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