movlw n_times ;get number of times to loop (must be > 0)
movwf loopcnt ;init number of iterations left
loop ;back here each new iteration
;
; This stuff gets run N_TIMES.
;
decfsz loopcnt ;count one less iteration left
goto loop ;back to do next iteration

Of course this assumes that the direct register bank is set for access to
LOOPCNT, and that 1 <= N_TIMES <= 255.

Just before your piece of code to loop you load a variable (register) with
the number of times the loop is to run. At the end of your piece of code
you decrement the variable and test to see if it has reached zero with the
command 'decfsz variable'. Then you have the 'goto step1' as the command to
skip when the variable has been decremented to zero.

For tight memory situations you can use the fsr register to hold the
counter.

For loops greater than 256 you can nest counter variables.

Use equates and lots of labels - they cost you nothing in the final hex
file, but aid a great deal in organising and self documenting your source
code.

loadloop ;label the start of the routine
movlw loopnumber ;get the number from an equate in
your header file
;(or from a variable if it has to be
calculated each time)
movwf loopcounter ;copy it to the counter variable
step1 ;label the start of the loop
nop
nop ;do your loop
nop
decfsc loopcounter ;decrement and test the counter = zero
goto step1 ;jump back if loopcounter <> zero
step1end ;label the end of the routine

> Use equates and lots of labels - they cost you nothing in the final hex
> file, but aid a great deal in organising and self documenting your source
> code.
>
>
> loadloop ;label the start of the routine
> movlw loopnumber ;get the number from an equate in

I certainly agree about using symbolic constants, but using labels to
document sections of code is a bad idea. Use comments instead. A label in
code is a warning that execution can end up there due to a CALL or GOTO and
not just due to falling thru from the previous instructions. All GOTO
targets should have a comment explaining why or when something jumps there.
Because labels require extra attention in understanding code, they should
only be used when necessary.