Searching \ for '[PIC]: Basic question about macros' in subject line. ()
Make payments with PayPal - it's fast, free and secure! Help us get a faster server
FAQ page: www.piclist.com/techref/microchip/languages.htm?key=basic
Search entire site for: 'Basic question about macros'.

Exact match. Not showing close matches.
PICList Thread
'[PIC]: Basic question about macros'
2002\02\15@040138 by Ray Gallas

flavicon
face
This is a beginner question, so I apologise if it seems dumb --
I've been studying various assembly programs and I've noticed that many
of them invoke an assembler directive, "MACRO".

Now from what I can see (and perhaps I'm missing something here), they
seem to fill essentially the same role as a subroutine.  That is, they're
a predefined set of commands, which at some point in your program, you
would have to, well, *define*.  It seems to me that doesn't really save
you much work over just calling a subroutine, which you also write out.

Obviously, MACROs must have some good reason for existing, otherwise,
why would anyone use them?  So my question is, what's the difference
between a MACRO, and just using a subroutine?  Why would one choose one
over the other in a given situation?

Thanks for any clues!

--
http://www.piclist.com hint: To leave the PICList
spam_OUTpiclist-unsubscribe-requestTakeThisOuTspammitvma.mit.edu


2002\02\15@041748 by Michael Rigby-Jones

flavicon
face
{Quote hidden}

A subroutine is a single section of code that can be called from multiple
places in your code.  To invoke a subroutine on a PIC, you use the "CALL"
instruction, when the subroutine has finished, you use the "RETURN"
instruction to jump back again.  Each time you use a "CALL", you place the
PIC's program counter onto the stack.  The stack on most PIC's has room for
only 8 program counter values, so you can never nest more than 8 "CALLS".
When you call a subroutine, the call and return take some time to execute (2
cycles each on low/midrange PIC's).

A MACRO looks similar to a subroutine, but works in a very different way.
The assembler uses a pre-processor that essentialy performs a "serach and
replace" when you assemble your code.  Everywhere you have invoked a macro
in your code, the entire code of that macro will be placed there. If you
invoke a macro 5 times in a row, then 5 copies of the macro code will be
placed one after the other in your program.  This is obviously not very
efficient if your macro is large (in which case you should think about using
subroutines), but for a small macro's this makes the code execute more
quickly (not CALL/RETURN) overhead, and uses no stack.

Typicaly, macro's are used to perform short functional blocks that do not
justify the time/stack overhead of a subroutine, but ones that may be needed
several times within your code.  Used properly, they can make writing and
reading the code easier, because the macro's can be given descriptive names.

Mike

--
http://www.piclist.com hint: To leave the PICList
.....piclist-unsubscribe-requestKILLspamspam.....mitvma.mit.edu


2002\02\15@054640 by Sergio Masci

picon face
----- Original Message -----
From: Ray Gallas <EraseMErgallasspam_OUTspamTakeThisOuTMYBC.COM>
To: <PICLISTspamspam_OUTMITVMA.MIT.EDU>
Sent: Friday, February 15, 2002 8:59 AM
Subject: [PIC]: Basic question about macros


{Quote hidden}

You are partly right, but...

If you have a small number of instances of use of the subroutine and the
body of the subroutine is short then you might find that the setup / call /
return / retsult overhead swamps any extra code produced by a macro
alternative.

Also since a macro produces code with 'inlined' arguments, this produces
faster executing code than using a more general subroutine.

An example of these two properties comined would be:

add16    .macro    arg1,arg2

               movf    arg1+0,w
               addwf    arg2+0
               movf     arg1+1,w
               btfsc    STATUS,C
               addlw    1
               addwf    arg2+1

               .endm

A subroutine version would look like:

add16x     movf    acc1+0,w
               addwf    acc2+0
               movf     acc1+1,w
               btfsc    STATUS,C
               addlw    1
               addwf    acc2+1
               return                        ;; return overhead

to use them you would need to do

               ;; for the subroutine version

               movf    fred+0,w        ;; call setup overhead
               movwf    acc1+0
               movf    fred+1,w
               movwf    acc1+1
               movf    bert+0,w        ;; call setup overhead (cont.)
               movwf    acc2+0
               movf    bert+1,w
               movwf    acc2+1

               call    add16x                ;; call overhead

               movf    acc2+0,w        ;; result overhead
               movwf    bert+0
               movf    acc2+1,w
               movwf    bert+1


               ;; for the macro version
               add16    fred,bert

               ;; which would produce this
               movf    fred+0,w
               addwf    bert+0
               movf     fred+1,w
               btfsc    STATUS,C
               addlw    1
               addwf    bert+1

Another advantage is that sometimes you need several copies of
the same subroutine that uses different working storage. In this
case you would write your subroutine once as a macro and then
just invoke it a few times with different working storage. Consider
the above add16x example. This subroutine could not be used
in an interrupt routine if it were also being used by the main line
code, without taking great care not to disturb the working storage
acc1 and acc2.

Yet another advantage is that macros (depending on the assembler
- xcasm definiatly suports this) can also generate their own local
workspace, making them suitable for use as inline libraries reducing
module linkage overheads. These are overheads that occure when
one function calls another in a seperately compiled or assembled
module.

Regards
Sergio

--
http://www.piclist.com hint: To leave the PICList
@spam@piclist-unsubscribe-requestKILLspamspammitvma.mit.edu


2002\02\15@102235 by Herbert Graf

flavicon
face
I think the biggest reason is code space. With a subroutine there is only
one instance of that subroutine in the code, all calls to it branch to that
address. With a macro you are using something called 'inline code', every
time you "call" the macro a copy of that code gets added, so 20 "calls" to
the macro, 20 copies of that code. Now whether this is a bad thing or not is
up to you and your circumstance. A macro consisting of 1 or 2 lines of code
is mostly better then a subroutine, a macro 30 lines long is probably best
done as a subroutine, but it's up to you. In timing critical applications it
MAY be better to use a macro since you don't have the overhead of the
subroutine call (which admitidly on a PIC is only two extra cycles, but that
might be important in certain circumstances, in other micro's calling a
subroutine can hit you with a relatvily large cycle penalty). TTYL

> {Original Message removed}

2002\02\15@110257 by Bob Barr

flavicon
face
On Fri, 15 Feb 2002 10:24:09 -0500, Herbert Graf wrote:

>I think the biggest reason is code space. With a subroutine there is only
>one instance of that subroutine in the code, all calls to it branch to that
>address. With a macro you are using something called 'inline code', every
>time you "call" the macro a copy of that code gets added, so 20 "calls" to
>the macro, 20 copies of that code.
Minor nit to pick - Subroutines get called, macros get invoked. Using
the term "call" when talking about macros muddies the distinction
between macros and subroutines.

>Now whether this is a bad thing or not is
>up to you and your circumstance. A macro consisting of 1 or 2 lines of code
>is mostly better then a subroutine, a macro 30 lines long is probably best
>done as a subroutine, but it's up to you. In timing critical applications it
>MAY be better to use a macro since you don't have the overhead of the
>subroutine call (which admitidly on a PIC is only two extra cycles, but that
>might be important in certain circumstances, in other micro's calling a
>subroutine can hit you with a relatvily large cycle penalty).

Oops, another nit - Actually it's four cycles minimum overhead for a
subroutine. There's the 2 cycles for the call and another 2 for the
return.

Regards, Nitpicker Bob

--
http://www.piclist.com hint: To leave the PICList
KILLspampiclist-unsubscribe-requestKILLspamspammitvma.mit.edu


2002\02\15@112158 by Herbert Graf

flavicon
face
{Quote hidden}

       I agree, that's why I wrote "call" instead of just call. TTYL

--
http://www.piclist.com hint: To leave the PICList
TakeThisOuTpiclist-unsubscribe-requestEraseMEspamspam_OUTmitvma.mit.edu


2002\02\15@115958 by Nick Veys
flavicon
face
Nobody has really mentioned the simplicity macro's can add to your
program.  I use them in some routines where I need to send several
pieces of data, simply use the macro:

MY_MACRO arg1, arg2, arg3, .....

and have the macro sort it out, make decisions, etc...  I love the damn
things.

RemoveMEnickspamTakeThisOuTveys.com | http://www.veys.com/nick

--
http://www.piclist.com hint: To leave the PICList
piclist-unsubscribe-requestEraseMEspam.....mitvma.mit.edu


2002\02\15@134652 by Giles

picon face
Some of my simple MACROs

; Macros for simplifying using the Status bits
IF_ZERO macro
btfsc STATUS,Z
endm
IF_NOT_ZERO  macro
btfss STATUS,Z
endm
IF_NEGATIVE  macro
btfss STATUS,C
endm
IF_NOT_NEGATIVE macro
btfsc STATUS,C
endm
IF_CARRY  macro
btfsc STATUS,C
endm
IF_NOT_CARRY macro
btfss STATUS,C
endm

--
http://www.piclist.com hint: To leave the PICList
EraseMEpiclist-unsubscribe-requestspammitvma.mit.edu


2002\02\15@151046 by Bob Barr

flavicon
face
On Fri, 15 Feb 2002 12:44:18 -0600, Giles wrote:

{Quote hidden}

As an alternative, if you're using MPLAB, there are built-in
'pseudo-ops' SKPZ, SKPNZ, SKPC, and SKPNC as well as some others.

Ref: MPASM User's Guide, DS33014G, Table B.11

Regards, Bob

--
http://www.piclist.com hint: To leave the PICList
RemoveMEpiclist-unsubscribe-requestEraseMEspamEraseMEmitvma.mit.edu


2002\02\19@151351 by Harold M Hallikainen

picon face
On Fri, 15 Feb 2002 00:59:40 -0800 Ray Gallas <RemoveMErgallasspam_OUTspamKILLspamMYBC.COM> writes:
> Obviously, MACROs must have some good reason for existing,
> otherwise,
> why would anyone use them?  So my question is, what's the difference
> between a MACRO, and just using a subroutine?  Why would one choose
> one
> over the other in a given situation?
>

       When the assembler finds a call subroutine instruction, it inserts the
CALL instruction with the address of the subroutine. The existing program
counter is put on the stack and the address of the subroutine is put in
the program counter. When the return instruction is encountered by the
processor in the subroutine, it pulls the return address from the stack
and continues execution with the instruction after the call.
       With a macro, on the other hand, the actual code of the macro is
inserted into the program EVERY TIME THE MACRO IS "INVOKED." So, using a
macro invocation (sounds religious, doesn't it...) results in a larger
program. However, it is a little faster (no return address storage and
recovery) and results in a less deep stack (which can really be a concern
on a PIC... How many times have you been deep in mainline code subroutine
calls and then have an interrupt cause a stack overflow?).
       What I REALLY like about macros is the use of big arguments and multiple
arguments. For example, the code below calls a subroutine that puts a
message up on the lcd, but I don't have to deal with loading the high
byte and low byte of the pointer into the message. Just call it as
MsgToLcd(SomeMessage) and it happens!


MsgToLcd macro msg
; Set up pointers and send a messag to LCD
       movlw   high(msg)
       movwf   MsgHi
       movlw   low(msg)
       movwf   MsgLo
       call    LcdMsg
       endm


       I also have macros for setting banks (bank0, bank1, bank2, etc.) so I
don't have to remember all those rp bits. I also have macros for
saveContext and RestoreContext for use in my interrupt service routine.


Harold

FCC Rules Online at http://hallikainen.com/FccRules
Lighting control for theatre and television at http://www.dovesystems.com

________________________________________________________________
GET INTERNET ACCESS FROM JUNO!
Juno offers FREE or PREMIUM Internet access for less!
Join Juno today!  For your FREE software, visit:
dl.http://www.juno.com/get/web/.

--
http://www.piclist.com#nomail Going offline? Don't AutoReply us!
email RemoveMElistservTakeThisOuTspamspammitvma.mit.edu with SET PICList DIGEST in the body


2002\02\19@212112 by Olin Lathrop

face picon face
> > Obviously, MACROs must have some good reason for existing,
> > otherwise,
> > why would anyone use them?  So my question is, what's the difference
> > between a MACRO, and just using a subroutine?  Why would one choose
> > one
> > over the other in a given situation?

I didn't see the original message for some reason.  I see Harold has already
given you a good answer, so I won't repeat what he said.

I rarely use macros as just subroutines without the 4 cycle call/return
overhead.  I think of macros more as canned but possibly configurable code.
The parameters you pass to macros allow compile time choices to be made,
which allows for just the right code to be emitted in different situations
with considerable complexity.  You only having to work out the details once
when you write the macro.

I use a large set of standard macros accross all my projects and keep them
in a master include file.  Go to http://www.embedinc.com/pic and take a look
at STD.INS.ASPIC for many macro examples.

Another use for macros is to perform some canned assembly time operation.
Macros don't have to emit any code.  An example of this is the UART_BAUD
macro in the file I mentioned above.  It uses assembly time constants and
variables to compute the best UART setup values given the clock frequency
and the desired baud rate.

Especially take a look at the DBANKIF macro and related macros.  If everyone
used these or something similar, a number of the problems posted to the PIC
list would go away.  I very rarely have bank switching bugs in my code, and
if I do it's usually because I left out a DBANKIF or forgot to put an UNBANK
at a label that can be jumped to from different places.


********************************************************************
Olin Lathrop, embedded systems consultant in Littleton Massachusetts
(978) 742-9014, EraseMEolinspamspamspamBeGoneembedinc.com, http://www.embedinc.com

--
http://www.piclist.com#nomail Going offline? Don't AutoReply us!
email RemoveMElistservKILLspamspammitvma.mit.edu with SET PICList DIGEST in the body


More... (looser matching)
- Last day of these posts
- In 2002 , 2003 only
- Today
- New search...