Clever macro use

;Example of use of macro in the code:
;		SBIC	PORTD,2
;		FORDNZ ,R16      ;do something ind(R16)times
;		SBIS	PORTD,2
;		FORDNZ ,R17  ;do somethingelse ind(R17) times

;the macro:
FORDNRZ	MACRO	function,loopreg
		;for-next loop, down to zero counting,
		;function is  loopreg is counter reg
		local LOOP
		local OUT
		RJMP	LOOP	;for one-liner compatibility, jump straight into loop
		RJMP	OUT	;or skip one line and jump out
LOOP		function	;excecute the function to be repeated 
		TST	loopreg
		BREQ	OUT	;branch OUT if zero (function excecuted at least once)
		DEC	loopreg ;dec here, so that function sees correct loop value
		RJMP	LOOP	;else next
OUT		ENDM

One caveat, though;
Don't forget that macros get expanded! It's easy to forget and to land yourself in trouble. Consider...
	sbic	PIND,5	     ;don't show string if clear
	display errormsg     ;PIND, 5, set, so show error
	clr     temp	     ;clear temp for next test
	...
Of course, when this gets expanded, you will skip the first instruction of your macro when the bit is set, and do all the rest of them, leaving you wondering why your code prints the error message when it should, and then either the error message of some other garbage, when it should print nothing.


Thanks to John Stiekema for this.