.nolist ; avr_registers.inc - my CPU register usage and naming for AVR ; author Neil Franklin, last modification 2008.10.22 ; register usage and calling convention ; callee-push/pop minimises code but allways runtime overhead ; caller-push/pop minimises runtime overhead but repeated code ; large register sets like AVR allow splitting registers into 2 groups ; some used for callee, caller pushes, only if it needs these ; some used for caller, callee pushes, only if it needs these ; with an good splitting policy only push/pop in multilevel calls ; instruction set specialty registers ; address registers for X Y and Z modes ; 16bit pairs, use *H:*L naming, T = Temporary .def XL = R26 ; often 2 pointers quickly needed, not Y .def XH = R27 ; callee may use any time, caller push if still in use .def YL = R28 ; only non-Z with +q addresseing, potential frame pointer .def YH = R29 ; must stay robust, callee push if used as third .def ZL = R30 ; often special use, often changes, ideal for temp .def ZH = R31 ; callee may use any time, caller push if still in use ; other registers for 16bit arithmetic (adiw, sbiw) ; 16bit pair, also *H:*L naming, D = Double, A = Accumulator .def AL = R24 ; never changed unneccessary, can have lasting stuff .def AH = R25 ; must survive entire caller, callee push if used ; registers for multiplication result ; 16bit pair, also *H:*L naming, M = Multiplication .def ML = R0 ; change at any multiplication, not lasting stuff, also temp .def MH = R1 ; callee may use any time, caller push if still in use ; instruction set normal registers ; registers with immediate instructions (ldi, subi, sbci, cpi, andi, ori) ; are rest of R16..R31, gives R16..R23 ; immediate (loop) counters, C = count .def C0 = R16 ; must survive entire loop, callee push if used .def C1 = R17 ; immediate accumulators for general computation, A = Accumulator .def A0 = R18 ; must survive entire caller, callee push if used .def A1 = R19 ; immediate temporaries (and parameters) for general computation, T = Temp .def T0 = R20 ; often changed, callee fast usage, caller push if still in use .def T1 = R21 ; immediate for interupts, I = Interrupt .def I0 = R22 ; not used in normal code, only for interrupt, ISR without push .def I1 = R23 ; therefore also survive between multiple interrupts ; without immediate instructions ; are rest of R0..R15, gives R2..R15 ; no non-immediate (loop) counters, as usually loaded with ldi ; preferably missuse an temp or push/pop if 3rd nested loop is needed ; non-immediate accumulators for general computation, A = Accumulator .def A2 = R2 ; must survive entire caller, callee push if used .def A3 = R3 ; non-immediate temporaries (and parameters) for general computation, T = Temp .def T2 = R4 ; often changed, callee fast usage, caller push if still in use .def T3 = R5 ; non-immediate for interupts, I = Interrupt .def I2 = R6 ; not used in normal code, only for interrupt, without push .def I3 = R7 ; therefore also survive between multiple interrupts ; non-immediate fast global variables, G = Global ; also (miss)use for other/special purposes, reserve specially .def G0 = R8 ; must survive entire program, callee push if used .def G1 = R9 .def G2 = R10 .def G3 = R11 .def G4 = R12 .def G5 = R13 .def G6 = R14 .def G7 = R15 .list