[comp.sys.amiga] To macro, or not to macro?

Sullivan@cup.portal.com (sullivan - segall) (05/30/89)

I've been arguing out the fine points of whether or not macro assembly
is good programming style on a local BBS (Digital Mail Box 408/258-5463.)
Do macro enhance legibility, or decrease it?  When should they be used, 
and when should one resort to subroutines instead?  
  
I felt that it would be better to open the question to a wider community.
Below is an edited message tree as the discussion stands thus far.  I would
be very interested in other opinions. -kls


_________________________________________________________________

/V\  Sullivan  was the first to learn how to jump  without moving.
 '   Is it not proper that the student should surpass the teacher?
To Quote the immortal Socrates: "I drank what?" -Sullivan
_________________________________________________________________

Mail to: ...sun!portal!cup.portal.com!Sullivan or
         Sullivan@cup.portal.com
----
From: Stephan
  To: Mr. Raster (X)

 Since when you boot up, the 68020 turn the cache off and you need to set it
from 'softwar'.Look pretty simple to do, I might even do it know. The only
thing is that I don't have a 68020 compiler:-( And I can't get the developer
package from michtron for Devpac...
 Maybe setcpu can do the job.I heard that some user group order 13 board!
They must be pretty happy with it..

Reply(s) #11625 #11628 

Msg: #11628  Sec: 6 - the Amiga chulkboard
      23-May-89  09:54 PM
Subj: #11616 - ?! (R)
From: Kevin Smathers
  To: Stephan (X)

Don't let a lack of assemblers stop you.  Just define a macro which is a dc.w
with the correct words for turning on the cache.  (If you want to distribute
it you may prefer to actually check the CPU first.) All of the old Intel 8080
assemblers were updated to the expanded instruction set of the Z80 with
macros when it first came out.  Many people still prefer programming in
extended Intel opcodes over Zilog opcodes.  -kls

Reply(s) #11633 #11730 

 Msg: #11633  Sec: 6 - the Amiga chulkboard
      23-May-89  12:47 AM
Subj: #11628 - ?! (R)
From: Stephan
  To: Kevin Smathers (X)

 That's a idea for the cache, but I don't see myself making 200 macros or
more!
 If you have the 68020 user manual you will se that it include more than
maybe 600 opcode! will all those addresing mode..
 But I really dind't of that for the cash.Even that need some reading... I
wont think of it, untill I find that setcpu wont work...Hope not:-) Well you
know the 65x0 INC instruction? well on the 68000 you can use a macro using
addq #1,
 I like to see what go in the file, with macro it's alway stuff hiding from
you -> the way to C:-) I like to C what I asem...

Reply(s) #11674 

(UA RE Q) (Delete): rr

 Msg: #11674  Sec: 6 - the Amiga chulkboard
      24-May-89  10:13 PM
Subj: #11633 - ?! (R)
From: Kevin Smathers
  To: Stephan (X)

600 new opcodes on the 68020?!?  Good god.  There it would be a lot nicer to
have a real 68020 assembler.  Also macros aren't really capable of doing
error checks on their parameters so bad code is hard to kick out.
  Increment, decrement, and clear are all common macros.  MoveQ #0,Dx is a
lot faster than CLR.L Dx.  Also you could use a CLRA macro which invokes
SUB.L Ax,Ax.  Macros are just handy ways of extending the built in language. 
They shouldn't be used for whole subroutines, after all, that is what
subroutines are for.  In general if a macro is more than 10 instructions long
I use a subroutine instead.
  My favourite macro is LDIR of Z80 fame, which moves a segment of memory Dx
bytes long from (Ay) to (Az).  Using macros is a lot easier than spelling out
each load and branch individually, and the routine is too simple to make into
a subroutine (that would be overkill.) -kls

Reply(s) #11685 #11731 

 Msg: #11685  Sec: 6 - the Amiga chulkboard
      24-May-89  11:42 PM
Subj: #11674 - ?! (R)
From: Stephan
  To: Kevin Smathers (X)

 Well I use moveq to clead data register, suba for addrss register But dont
use macro.
 Well on the amiga you could use the blitter to copy data! not in a macro but
in a librayr, Well great idea:-) next function in the nslibrary:-)
 You can make that macro.
    move.w  #X,dx 1$
    move.b  (a0)+,(a1)+
    dbeq    d0,1$

That also put the 68010 in loop mode, faster... less bus cycle, when running
in chip ram, still better in fast than a 68000.
 I don't like to use macro, Try to read other program with their own macro
you need a copy of EACH macro to see whats going on, that's why I use ZERO
macro in my programs.

Reply(s) #11782 

Msg: #11782  Sec: 6 - the Amiga chulkboard
      27-May-89  12:57 PM
Subj: #11685 - ?! (R)
From: Kevin Smathers
  To: Stephan (X)

Once you know what the macros are though it is a lot easier to read code
written with them.  For instance, it is easier to recognize
    ZERA  A0
    ZERD  D0 than
    SUB.L A0,A0
    MOVEQ #0,D0

Your memory move sequence is almost exactly what I use for LDIR and LDDR
macros.  Let me put it another way.  To understand a program with lots of
macros all you have to have is a good reference to what the macros mean.  To
understand a program written without them you likewise have to know what the
opcodes mean, but you also have to remember lots of little bits of trivia,
like what is the fastest way to clear a data register or an address register,
how do you specify a loop which is short enough to put the 68010 into loop
mode for memory moves, etcetera.

Macro names are designed to be mnemonic and simple.  If they don't make a
program easier to read rather than more difficult then they shouldn't be
used.

I use macros for inline string compares.  It is a lot easier to look at
STRCMP A0,A1 than it is to look at the small subprogram required to do the
string comparison, but for speed it is also much faster than using an entire
subroutine call.   (Think about it.  Basically it is like adding string
opcodes to the 68000 instruction set, only they are really just pseudo ops.)

Reply(s) #11803 

Msg: #11803  Sec: 6 - the Amiga chulkboard
      27-May-89  06:12 PM
Subj: #11782 - ?! (R)
From: Stephan
  To: Kevin Smathers (X)

 :-) I have to disagrea with 90% of what you said... First for me CLR=0 to
destination, ok you use CLRD, me ClearData somebody else ClearD You still
have to look what to guy do in his call.
 I don't alway clear a0 long size, sometime I will use address registr for
and only clear the 8 fisrt bit.... Macro is confusing!
 Secondly macro EAT your memory if used for subprogram and will only save you
a couple of cycle! it's not a bsr and rts that will take over the 68000:-)
 For string I used library... Why have 1000 copy of the same rouitne in 10
diferent program run at the same time!
 But people should add macro 'has' opcode like that, it would be a mess! I
already find the 68000 pretty full of opcodes, I would use macro maybe for
library call, loading the base address and make the call, but a6
 is not a temporary register.So in a look that will call for example 1000
time the GFX library I wont have to load the base address.But I will only
save 20,000 cycle here:-) (5000 bus read cycle).
 If you use macro, make a library out of it and document it.not thing like
moveq->clr but routines, you told you where using macro instead of
subroutine...
 I telling you have to guess what a macro do, and to be sure you have to look
at it.
 I saw some early macro pasted on the amiga section (maybe not here) mostly
string handling macro.Those macro should be used has subroutines.
 like:

Right:
  CallRight a0
  rts But I have to agree that if you want to use macro has 'opcode' is the
perfect solution!
 I use include instead of macro to include subroutines. Anyway it's a style,
but I anderstand a sources without macro faster.

Reply(s) #11807 #11836 

Msg: #11807  Sec: 6 - the Amiga chulkboard
      27-May-89  07:44 PM
Subj: #11803 - ?! (R)
From: Chris Green
  To: Stephan (X)

  Another thing is that if you use a memory move macro for every memory move
you do, your code will probably run slower...If moving medium sized or large
blocks, it is better to have a subroutine which aligns the addresses, moves
long words, and moves multiple longwords per iteration to save loop
overhead... that routine is too big to put inline.

Reply(s) #11809 

Msg: #11809  Sec: 6 - the Amiga chulkboard
      27-May-89  09:18 PM
Subj: #11807 - ?!
From: Stephan
  To: Chris Green

 Yes, or why not using the blitter for multy mdedium-large block copy...
Anyway that limit you to the first 512k:-( I don't think any developer will
use it for 1 meg machine since the new chip set is not spread enought!
 But I still use the blitter for inside window smooth scrolling, And I'm sure
my routine is more eficient than ScrollVport.
 Well I copy alot small bock of mem, like for a requester qetting the file
name...I put my 68010 in loop mode puting #-1 in d0 and loop until move.b
(a0)+,(a1)+ copy the null byte and terminate the loop (dbeq). I don't move
mutch data around exepted chip data with the blitter and small data in loop
mode, both are VERY efecient way to get the job done.
 So in you routine you check bit 0 and if so you copy the first byte sub 1 to
the count, than lsr it by 2 (div by 4) now you CAN't get a odd number
twice:-) But you check bit 1 clearit, save it and long copy,
 if bit 1 was set do a word copy... that's it I guess take care of the case
count of 3...
 Should around 10-15 instruction. And you can get the long copy in loop mode
for the 68010! Not a bad idea I will try that:-)
 680x0 assembly is THE BEST! I try alot and these the first I felt good with,
Well I dont have data from left to right:-)
 By the way, someone is coming with a 3D library, most of the routine used on
the IRIS workstation.

Msg: #11836  Sec: 6 - the Amiga chulkboard
      28-May-89  07:55 PM
Subj: #11803 - ?! (R)
From: Kevin Smathers
  To: Stephan (X)

Umm.... a very badly defined macro would force you to reload (eg.) A6 every
time you use it, but a well written one would not.  Typically for macros, if
a parameter is left out then the macro assumes that the register which would
require it has already been loaded.  For instance

      GFXCALL LVO_whocareswhat, GFXBASE

 would load GFXBASE into A6 before calling LVO_whocareswhat(A6), while

      GFXCALL LVO_whocareswhat

 would assume that A6 has already been loaded.

So you see using macros doesn't have to be a disadvantage.  As for string
compares, the actual subroutine to count the string length, or to compare two
strings is less than ten instructions long.  BSR is great if the relative
offset is within 64k, otherwise it is SLOW.  In line code can speed up tight
loops by double that required for subroutine calls.  Anything this small
*should* be duplicated thousands of times if neccessary.  We aren't working
with Z80's here.  There is at least 400k available for applications,  we
don't have to scrimp on every byte of code.

I find just the opposite with respect to the opcode set of the 68000.  There
are far too few opcodes.  That is a fact which is both good and bad.  Since
there are very few opcodes it is easy to create macros because none of the
opcodes are taken.  On the other hand I can't read

     MOVE D0,(-A7)

 because it should be (which is much more intuitive)

     PUSH D0 [,A7]

 in macros the optional parameters are a useful tool.  If not specified just
make them the default, otherwise use the item specified. Instead of
specialized opcodes, Motorola decided to use a menagerie of addressing modes.
 I like opcodes more than addressing modes.  That was the problem with the
Z80 instruction set.  Everything that the beast could do was in a LD
instruction. -kls

Reply(s) #11839 #11848 

sg: #11848  Sec: 6 - the Amiga chulkboard
      28-May-89  11:00 PM
Subj: #11836 - ?! (R)
From: Stephan
  To: Kevin Smathers (X)

 Here again! can't you write jsr _xxx(a6)   intead of CLVOCALL or somethinf
the like!?! And I don't alway use a6 for dos dos, for speed I use a5 in tight
loop where I need 2 diferent call to librarys!
 you can't read d0,-(a7)? hey assembly lenguage isn't C the good thing about
it is you don't have to pass 2 year learn off the functions, restriction,
format etc... etc...
 I'm sory but move d0,-(a7) I find that better than push, because in push you
need the notion of stack pointer and knowing also that it decrement the
destination before ->>>MOVING<<<<--- the data!!!! My stringlenght routine is
4 instruction and 10 byte loop, with 1 instruction in the loop itself.And it
work with string of 4 gigabyte long:-) I still don't see the point of macro,
it's a extra work that you don't have to do, and if you alway want to use
them it's a limit.
 I 68000 don't need stuff like PUSH COPY, they are already there with
equivalent names.What you are trying to do is 'customizing' it for
'yourself'.
 I don't use small subrouitne in short loop, but I use them in the program
itself.Because you source will be cleaner and if you call the function only
10 time in a large program, I prefere to have a source 100 lines smaller and
deal with a couple of extra cycles.
 But I don't say you shouldn't use macro, just macro are not my style.

Reply(s) #11896 

Msg: #11896  Sec: 6 - the Amiga chulkboard
      29-May-89  09:02 PM
Subj: #11848 - ?!
From: Kevin Smathers
  To: Stephan (X)

Hell, a hundred lines is about 500 bytes which is less than the length of
this message.  Everyone has their own way of doing things I suppose.  Ever
since I got a good macro compiler I've reserved subroutines for things that
really need them.  (Ie: over 10 instructions in length.) Lots of addressing
modes confuse me.  It is easy to forget whether a particular mode is indexed
relative, or absolute, or some other weird mixture.   I'm never sure how the
assembler is going to resole relative references.  Are they *specified* as
relative offsets, or do you just use a label and the program will
automatically create a relative offset. Macros are (for me) a lot easier to
remember.

I will say though that given current decompilers, writing lots of direct code
helps you figure them out a lot faster.  I was staring at some code I'd run
through ReSource the other day.  I sure wish it would decompile to standard
macros.  :) -kls


Msg: #11806  Sec: 6 - the Amiga chulkboard
      27-May-89  07:41 PM
Subj: #11784 - ?! (R)
From: Chris Green
  To: Kevin Smathers (X)

 Oh, OK. I generally don't use macros for things like that as they can cause
a lazy programmer (like me) to generate extra code. Often, there are special
circumstances which can be taken advantage of when doing things like moving
memory. For instance, one of the addresses, or the count (or one of the
addresses-2, or the count +1) is already available.. also, macros which
modify registers without you explicitly telling it to can make code either
hard to read or buggy. Basically I use macros when:
  a) they only ass4emble to one instruction, like PUSHM and POPM (which
      assemble to MOVE.L regs,-(a7) or b) in special cases in one place in
the code ... like a character
      plotter needs a sequence of 3 or 4 instructions repeated 8 times.
      Better to use the assembler REPEAT pseudo-op if the code is
      the same all 8 times, though. or c) for generating structured data.
 That's on the 68000 and 8086...on the 6502 I go crazy without a whole bunch
of macros.

Reply(s) #11837 

Msg: #11837  Sec: 6 - the Amiga chulkboard
      28-May-89  08:11 PM
Subj: #11806 - ?!
From: Kevin Smathers
  To: Chris Green

In general I make D0, D1, A0, A1 all scratch.  I can do anything I want to
with them at any time, even in the middle of a macro.  (Subroutines do the
same.)  When I write the macro I document the inputs and outputs including
side effects so that I can use them if they are handy.  If I'm lazy I just
avoid using those registers.

All macros should be defined so that they don't require parameters which are
already defined.  MEMNCPY, or LDIR (whichever you prefer) should look like.

   LDIR [[source] [,[dest] [,[count] ]]]

Source and dest can either be address registers or memory labels.  If labels
the macro should generate:

   LEA source,A0
   LEA dest,A1

Otherwise the registers specified should be substituted for A0 and A1
throughout the macro.  Count if specified as a label should be loaded into
D0, and if given as a register should be substituted for D0 through out the
subroutine.

Side effects would be:

 Source <- Source + Count
 A0 <- Source (if label)
 Dest <- Dest + Count
 A1 <- Dest (if label)
 Count <- 0
 D0 <- Count (if value)

MAcros such as these are easily defined.  It doesn't take very much work to
avoid generating extra code because of the macro.  What does take time is
looking up the side effects when you aren't sure what they are.  If you
meticulously avoid using the scratch registers you won't have to worry about
side effects, but you may be losing some useable information.

Macros that need more than the scratch registers either PUSH and POP, or
become subroutines (which in turn push and pop.) -kls



---- [EOF] ----

lphillips@lpami.wimsey.bc.ca (Larry Phillips) (06/03/89)

In <18958@cup.portal.com>, Sullivan@cup.portal.com (sullivan - segall) writes:
>I've been arguing out the fine points of whether or not macro assembly
>is good programming style on a local BBS (Digital Mail Box 408/258-5463.)
>Do macro enhance legibility, or decrease it?  When should they be used, 
>and when should one resort to subroutines instead?  
>  
>I felt that it would be better to open the question to a wider community.
>Below is an edited message tree as the discussion stands thus far.  I would
>be very interested in other opinions. -kls

I guess it all depends on what you call legibility, or what makes things easier
for you to read.  I don't think the question is one of macros vs.  subroutines,
since they are two completely separate things, each having their own strengths
and weaknesses.  Personally, I feel that subroutines should be used for
routines that are needed in a lot of places, and that are of significant size.
Macros come in handy for two differnt things.  The first is the small two or
three liner that you use in many programs, and that are too small or
inefficient when implemented as subroutines.  The second, and to me, most
important use of macros is to do the 'setup' for a subroutine call.

An example might be a routine that prints a NULL terminated string, first
finding the length of the string by scanning for the NULL. This is signficant
in terms of size, and could be called a lot in a program, so should be made a
subroutine. The macro that calls it can be perfectly understandable, and in
fact I see no difference at all in the readbility between:

		lea	label,a0
		bsr	printit

and...

		print	#label


As for efficiency, yes, the macro can be less efficient. Take a look at the
above two calls. The first used an LEA opcode, while the second generates a
MOVE.L and a BSR.  The reason for this is to make the macro more general, so
that I can call it with:

a string at a label...                   print #label
a pointer stored at a label...           print label
a pointer contained in a register...     print d5 
or a pointer to a pointer...             print (a4)
or a pointer in an array of pointers...  print 0(a3,d0.w)

The inefficiency comes when my macro is defined as:

print  MACRO
       move.l  \1,a0
       bsr     printit
       END

and I happen to want to print the string at an address contained in A0..

       print  a0

which will, of course generate:

       move.l  a0,a0
       bsr     printit

Considering the number of times this might happen, vs. the number of times I
call print, it is usually worthwhile. It is certainly no worse than I have seen
in disassembled C code.  If I want to get picky, I can just call it as:

       bsr    printit

if the pointer is already in A0.




A few comments on the comments included from the debaters...

>> Secondly macro EAT your memory if used for subprogram and will only save you
>>a couple of cycle!

Not necessarily so. short, two or three line macros, consisting of code you
would write inline anyway, are no different than typing them in, except that if
you don't put them in a macro, you have to type them in. Some things are best
done inline, taking the memory hit, if you are optimising for speed. the bsr
and rts might be 30% or more of the total time if the function is coded as a
subroutine. Clearly, it is strictly a matter of readability, which is rather
subjective (I can read asm easily. I cannot read C easily. I bet the reverse is
more prvalent on this net).

>>First for me CLR=0 to destination, ok you use CLRD, me ClearData somebody
>>else ClearD You still have to look what to guy do in his call.
>> ...
>> I telling you have to guess what a macro do, and to be sure you have to look
>>at it.

Are subroutines any different?  You have to look at them in order to see what
they do.  In what way is a macro less clear than a subroutine?  Assuming you
have the code for the subroutine or macros (if you don't, you'll have to guess,
and rewrite them anyway), there really is no difference.

>> For string I used library... Why have 1000 copy of the same rouitne in 10
>>diferent program run at the same time!

Rather depends on what you need to do with strings. If I only have a few things
I need to do with strings, and if the data is such that I can perform
optimizations in the specific case that are not applicable to the general case,
why have the general case in there? Why have the general cases for all string
functions in memory if you only need a few string functions? Again, macros and
subroutines serve two entirely different purposes.

>>Inline code can speed up tight loops by double that required for subroutine
>>calls.  Anything this small *should* be duplicated thousands of times if
>>neccessary.  We aren't working with Z80's here.  There is at least 400k
>>available for applications, we don't have to scrimp on every byte of code.

Right...  but there are times when speed is not as important as size, and
that's when you use subroutines (even small ones) for often called functions.
You generally cannot optimize efficiently for both speed and size.  Again,
macros and subroutines serve differnt purposes.  You should use what is
appropriate in the circumstances, one or the other, or both together.

>> Here again! can't you write jsr _xxx(a6)   intead of CLVOCALL or somethinf
>>the like!?! And I don't alway use a6 for dos dos, for speed I use a5 in tight
>>loop where I need 2 diferent call to librarys!

Yes, you can write it that way for lib calls, but the _LVOxxx(a6) wrapped
around the actual function gets in the way of readability (for me, obviously
not for him). I think it's cleaner to use the macro. I like the idea of a
couple of different macros for the call....

    CALL    OpenLibrary     ; a6 already contains ExecBase
    LIBCALL DoIO            ; a6 needs to be loaded before the JSR
    CALLDOS Examine         ; a5 is used for GfxBase

In addition,if you happen to be using a linker as well, you can even include
the XREF within the macro definition, or use conditional assembly and the SET
pseudo-op within the definition, removing the need to worry about whether or
not you have already defined a label, or an XREF, and save yourself some time
typing it in again for each new program.

Looks cleaner to me.

>>I still don't see the point of macro, it's a extra work that you don't have
>>to do, and if you alway want to use them it's a limit.

Extra work? Hmm... when I type in a 4 or 5 line macro defintition, I type it in
once. The work saving comes from only typing in one line any time I want to use
it.

>> But I don't say you shouldn't use macro, just macro are not my style.

That's it in a nutshell, it's a question of style and preference.  Macros can
be overused, abused, can eat memory, and can generate inefficient code, but by
no means do they always do these things.  Macros, subroutines, inline code,
unrolled loops, taking advantage of things you already know..  all have their
place.

-larry

--
Van Roy's Law:  An unbreakable toy is useful for breaking other toys.
+----------------------------------------------------------------------+ 
|   //   Larry Phillips                                                |
| \X/    lphillips@lpami.wimsey.bc.ca or uunet!van-bc!lpami!lphillips  |
|        COMPUSERVE: 76703,4322                                        |
+----------------------------------------------------------------------+

doug@xdos.UUCP (Doug Merritt) (06/05/89)

In article <2454@van-bc.UUCP> lphillips@lpami.wimsey.bc.ca (Larry Phillips) writes:
>The inefficiency comes when my macro is defined as: [...]
>       move.l  \1,a0		[...]
>which will, of course generate:
>       move.l  a0,a0
>       bsr     printit

Although your point is in general quite reasonable, in this example
it is inappropriate because the extra overhead of the move will be
totally swamped by the overhead of the call to printit. There is
no conceivable situation in which the difference would be measurable.

Actually this just confirms your point that macro efficiency is often
not a problem. And in fact many macros in both assem and C will be
*faster* than doing a subroutine call, and this can be a *very* important
programming tool. It's often possible to get a 20% overall improvement
by converting a C call to a macro, and I've gotten far more than that
at times.

But it's important to be careful, when optimizing, not to spend any
time optimizing something that will never have a measurable effect.
This is often one of the earmarks of an expert programmer versus a
hacker-wanna-be (present company excluded, of course).
	Doug
-- 
Doug Merritt		{pyramid,apple}!xdos!doug
Member, Crusaders for a Better Tomorrow		Professional Wildeyed Visionary

lphillips@lpami.wimsey.bc.ca (Larry Phillips) (06/06/89)

In <375@xdos.UUCP>, doug@xdos.UUCP (Doug Merritt) writes:
>In article <2454@van-bc.UUCP> lphillips@lpami.wimsey.bc.ca (Larry Phillips) writes:
>>The inefficiency comes when my macro is defined as: [...]
>>       move.l  \1,a0		[...]
>>which will, of course generate:
>>       move.l  a0,a0
>>       bsr     printit

>Although your point is in general quite reasonable, in this example
>it is inappropriate because the extra overhead of the move will be
>totally swamped by the overhead of the call to printit. There is
>no conceivable situation in which the difference would be measurable.

 In my defense, I will point out that I said it was worth it, and that I would
call the subroutine only if I was being picky. :-)

>Actually this just confirms your point that macro efficiency is often
>not a problem. And in fact many macros in both assem and C will be
>*faster* than doing a subroutine call, and this can be a *very* important
>programming tool. It's often possible to get a 20% overall improvement
>by converting a C call to a macro, and I've gotten far more than that
>at times.

>But it's important to be careful, when optimizing, not to spend any
>time optimizing something that will never have a measurable effect.
>This is often one of the earmarks of an expert programmer versus a
>hacker-wanna-be (present company excluded, of course).
>	Doug

Yes, it's all to easy to be 'cycle wise and algorithm foolish'. There isn't much
point in scraping off a few cycles here and there in inline code (init,
cleanup, etc.), or in an inefficient algorithm (if there's a better one
available).

I have just finished the first cut of a 'find' program that runs like greased
lightning, and is less than 2500 bytes long. It searches a file that is built
by a companion 'updatedb' program, and uses a Boyer-Moore search algorithm. The
point being that the Boyer-Moore search is a massive improvement over the 'brute
force' search, and I probably gained more using it than I would have gained in
a week of hand optimization. How much more fun it is to tweak a piece of code
that takes 3 seconds than to tweak one that takes 10 seconds. :-)

I now find myself in a position of having both small size and good speed, so I
have room to juggle the two.

-larry

--
Van Roy's Law:  An unbreakable toy is useful for breaking other toys.
+----------------------------------------------------------------------+ 
|   //   Larry Phillips                                                |
| \X/    lphillips@lpami.wimsey.bc.ca or uunet!van-bc!lpami!lphillips  |
|        COMPUSERVE: 76703,4322                                        |
+----------------------------------------------------------------------+

stephan@cup.portal.com (Stephen Derek Schaem) (06/07/89)

 Well, I'm here..:-)
I will try to show some point that make me fell that way about macro, It's not
 just idea but *experience*...
1) Macro more or less readable?: It's true that 'big' macro (usally over 10 
 lines of codes) dont make mutch difference over subrouitnes if they are not
directly included in the source file... Since you will have to open the macro
file or include file to take a look at them... But for 'customizing' the 
instruction set I have to disagrea! PUSH A0 will wont be self explanatory, but
move Rx,-(sp) is clear.Small macro ask you to have them all in your mind when
reading a source...
 
2) Macro used for library call: Here again I have to desagrea, my reason is
for library that dont especialy need the base to be passed in a special
 address register.And here again there is no specification for macro ussage,
so it's free to the programer and will have to take a look at the macro file
to be sure how things are done.
 
3) Macro = sub: For macro equivalent in size to a subroutine, It *should* be
include in a .library.Since it is used at least once by your software and
you also make it available for other program than yours.Every routine make
to be efecient should be excluded! I have other things to say about memory
usage but I wont enumerate them here, just that I could say that 5% to 10% of
the data from a file sit around doing nothing!People should free up their
startup code and initialization data after being used...
 
4)The point make with CLR, CLEAR, ClearData: That was a explample give for a
ONE line macro NOT subroutine! The discusion was at the time;'Why use macro
to redifine existing opcode'.I desagrea that a macro should be used instead
of moveq... moveq #0,Dx is a good way since the ALL world know what it mean!
a macro will Force you, again, to look at it and see how it is done, was the
programer 'stupid' and use CLR.L instead of moveq #0 in a loop called 65536 
 times?!

5) Optimizing code: Library call can be used to get very small 'master' code
by not repeating thing over and over (or subrouitnes).The context was not for
speed, sory if I let anybody beleived it.Sometime I use a bsr.s to jump over 
a data area in the main code section and use move.l (sp)+,Dx just because
all registers are used and I want the address in a data register.. That's for
Size optimizing.. For speed A bsr-rts can do alot, have to agrea:-)

6)Xref or no Xref? Well I dont use a linker very often And I try to keep it
that way.I have all the address offset mostly use in a file using EQU and 
all one that I never use in another.That same me some time for compiling.
But I use Xref in some cases but not for library base offset.
jsr _Examine(ax) or Call Examine <- need dosbase in a6!,
 		    LIBCALL Examine,Dosbase <-will be loaded in a6!
		    CALLDOS Examine <- Well Witch address register?!
In the 'normal' way:-) jsr _XX(ax) work ALL the time, everybody how will read
the code now it, and ther wont be ANY confusion! You you have to pass time
writing a good macro that will at the end (if you want full control) be as big
as a normal code.It's good if you use only a6, but when you have Dos or other
and have 3 library base used at the 'same' time you do extra work for 'nothing

Question a preferences?: Maybe, But I can live easy EVEN better without macro.
Could you without sub or include:-)
Well I saw to maybe people abusing macro...
 
Stephan Schaem: There isn't any toy I can't Break:-)

stephan@cup.portal.com (Stephen Derek Schaem) (06/07/89)

 Talking about C and macro.Usally macro can be used in alot of context and
from that need to do 'extra' work for adjusting itself.
 Assembly code made from a C source is 'stupid', saving register that don't
need to be, using an inapropriate addresing mode etc.. etc.. and for opt
anything it should be well thought and usally a routine will only work in
the context you wrote it!
 I had a big discusion (over 10 hours) about C an ASM, and what I found is
some people think that well thought C can be equivalent to normal asm...
 I try to prove my point but they never wrote a line a asm code, So I'm
making a could of disassembly of C to show how uglly it's working!
 I use a very optimize routine for reading-sorting files, I alway use
the N=number of file, N+N-1+N-2+N-3 (N time) It's still faster than anything
I saw..
 Anyway, I just wnated to say 
That macro are not faster than sub (Well if you count 34cycle:-) for a short
number of call...
All depand on how big is the rouitne do, how long it take.You should think in
a %... In short loop called frequently the code should be directly writen
and optimized at the max to fit the environment!.
 If you still think macro for those cases, oh well.Since macro need most of
the need a little overhead processing, moving something to the right register.
Just that Could creat a slow down in some casses.
 And if you have an overhead or any thing related than it's not a macro anymor
in a sens!

bmacintyre@watcgl.waterloo.edu (Blair MacIntyre) (06/08/89)

In article <19191@cup.portal.com> stephan@cup.portal.com (Stephen Derek Schaem) writes:
>I will try to show some point that make me fell that way about macro, It's not
> just idea but *experience*...

I certainly hope you aren't implying that the rest of the people discussing
this don't have experience.  It's not a good way to jump into a discussion.
_I_ have *experience* in assembler and I _totally_ and _completely_
dissagree with you.  Absolutely.  But, anyway ...

>1) Macro more or less readable?
>2) Macro used for library call:
>3) Macro = sub:
>4)The point make with CLR, CLEAR, ClearData:

You essentially repeated the same arguments four times, that you feel that
macros make the code harder to read, mostly because people will not trust
them, so they have to look at them all the time.

- if you can't tell what it does by it's name, rename it.  That is the
  point of higher level primitives such as macros.
- if you do not trust the macros you are using, why are you using them?
  One of the main reasons for macros is that you can do something tricky
  or potentially easy to screw up ONCE and not worry about it.  All the
  little examples give so far are pointless.  There are ALWAYS special
  cases when it is better to do something straight, without a macro.  But
  if you are repeating the same 4 instructions over and over, doesn't 
  that tell you something?

>5) Optimizing code: 

Are you talking about optimizing code after it works or before?  If you 
are talking about after, by all means, tweek it to your hearts content.
If you are talking about _before_ or while you are writing it, I am 
reminded of a comment someone posted a while ago about the difference
between computer scientists and hackers ...

Get it working first ... slowly.  Who cares?  Then optimize.  Macros are
great for making it easy to do things CORRECTLY, if not efficiently.
You complain about reloading a6 during a libcall?  SO WHAT!!!  IF ( and
I emphasize the _IF_ ) that call happens to be in a part of the program
that is chewing a large percentage of the time, redo it.  AFTER YOU FIND
OUT!  Please!  Don't waste time optimizing stuff that isn't slowing 
down a program in a significant way.  I am reminded of an organization
that one of my employers told me about.  They had a policy that any
impovements/optimizations to their OS had to be run through a huge test 
suite and produce a noticable improvement in the execution of the code
before they were officially added ... 

Anyway, enough preaching.  It just annoys the hell out of me when people
start globally condeming macros because they do things like reloading
a register too much.   

>6)Xref or no Xref? Well I dont use a linker very often And I try to keep it
>that way.  

Why?  Religious issue?  Do you have something against modularity?!?!
Nevermind ... :-)

>You you have to pass time
>writing a good macro that will at the end (if you want full control) be as big
>as a normal code.

That's the point ... you don't _want_ FULL control!  Why do you think
higher level languages are so popular?  Let the machine do the grunt
work for you ... if you want to recode something over and over, fine.
Don't try to say that this is a _superior_ style.  It is your prefernce,
fine.  So do it.  Be happy.  It's you right! :-)

> [ using macros that specify which register the lib base goes in ]
>It's good if you use only a6, but when you have Dos or other
>and have 3 library base used at the 'same' time you do extra work for 'nothing

So why not write a better macro?  What is the matter with a macro that
has the following functionality:

	Call Blat [, parm1 [, parm2]]

	( if not specified, parm1 is a6, parm2 is nothing )

	- if parm1 is a?, us a? as the lib base ( ignore any parm2 )
	- if parm1 is d?
	    if parm2 is specified,
	    parm2 must be a?, trans d? to a? and use it as the lib base
	    otherwise, transfer it to a6 and use it as the lib base
	- if parm1 is a name
	    if parm2 is specified,
	    parm2 must be a?, trans name to a? and use it as the lib base
	    otherwise, transfer it to a6 and use it as the lib base


	So,
		Call Blat 
	means
		jsr Blat(a6)

		Call Blat,a5
	means
		jsr Blat(a5)

		Call Blat,d5
	means
		move.l d5,a6
		jsr Blat(a6)
		
		Call Blat,DosBase,a3
	means
		move.l DosBase,a3
		jsr Blat(a3)

	etc ...

What is the problem?
 
>Question a preferences?: Maybe, But I can live easy EVEN better without macro.

Sorry about your luck.

>Well I saw to maybe people abusing macro...

Well, I saw to maybe people abusing the english language ... what in the
heck is The Portal System, anyway ... :-)

As for "abusing macro", you already know my view on that.  Macros make
Assembler easier to understand, easier to write correct code quickly.

I don't care about efficiency of coding when I first write code.  I
care about efficiency of algorithms and _correctness_ of algorithms and
code.  Optimization comes later, _if_ it is needed.  

If it ain't broke, for heaven's sake DON'T FIX IT!

>Stephan Schaem: There isn't any toy I can't Break:-)

I can see why!

-- 
= Blair MacIntyre, bmacintyre@watcgl.{waterloo.edu, UWaterloo.ca}          // =
=   now appearing at the Computer Graphics Lab, U of Waterloo!           \X/  =
= "There's nothing the matter with BR that a shot gun blast wouldn't fix" cge =
= "It's not my fault, fatboy!" - Felder, pilot of TL Student Driver On Board  =

stephan@cup.portal.com (Stephen Derek Schaem) (06/11/89)

Ok you point is pass time writing macro so nobody can read my code?!
You choose to do as you like! I like to write thing fast and writing 900 lines
of assembly is not a problem.And one day I find that my macro dont do what I
need, well I have to rewrite a new macro and 'debug' it.
 The above have nothing to do with your last message Blair, just the way
I felt after reading it:-)
 Do you want to define experience to me? Should I add some in front of it to 
make you happy? ok let's do it that way.With **some experience** in 680x0 
seembly .Do you want my grade from my advanced classes I took:-)
 4 point make in 4 diferent area, well I dont master the english language
as you have POINTED.Do you want people like me to be *outlaw* of usenet 
 You should think of the poor one that never made it trought high school and
do not have english as first language.But if my posting ofend you I can
have it printed and checked for you and others.I would have Email the message
to you but there is 3 people (4) in that discution.
 Ok lets get back to Macro usage.

First you said I made said for time the same thing.Sory if I leted you think
that way but readable!=confusing .I could have both cases in a listing that
I can distinc where easly.
 Want people to write code in French?! Why should people write macro name
in english!!! You will say, 'subroutines are the same'.But I said 'macro
usage under 10 lines of code'.You will find almost zero sub that are under
5 instruction in my programs!
 Have you EVER took a program written by someone else to continue/debug it?
If yes you would have posted you last message, if no I anderstand:-)
Want to talk about optimizing:-)!!! MY last 48 hours where past one 
optimizing code.(48 hours of programing, but almost same as living).
 I write code in a very slopy way at the begining, I even write things in C
or Basic!(you see how low:-) and when it work, only then I start optimizing!
Optimizing a unfinish code is for sure a big LOST! Sometime I remove rouintes
because there where leading me to the bad way.
 If you see ushow4.0 you will anderstand better by view, the only macro I 
would have used is (cant name one seem 99% of the people wont know what is
it refereing too) one that call library.
 And since the code is SUPER optimized NO MACRO on earth could do the job!!!!
That's another point I didn't shoed because it was not in the 'good' programer
handbook.
 (reminder:macro should be used to free you up from 'repeat' or extra typing)
another thing :-)' Get it work.. Slowly.Who cres?' Do you beleive that?
-Macro used to do things corectly:Why do you want ASM to look like C DASM?!
-a6 lib call 'SO WHAT', I run a program for 1 hour looping all the time.
 What is the use to pass time written macro that you use less than 10% of
the time!!! Back to the loop: you have a routine called 100 time a second
(supose you are mutytasking, if you do some time:-) you load 100 time a 
register for nothing...right only 6000 cycle, but dont you have anything
better than right a *good* macro that only you *annderstand* to handle that?!
 You dont seem to andersand at ALL!Your macro wont work!!!!!!
a5=IBase
a6=EBase
jsr	_FreeMem(a6)
exg	a5,a6
;;;
...
jsr	_CloseWindow(a6)
exg	a5,a6
(*exec call)
 etc....
And there is other cases.. Why do you pass time writing kids stuff for macro
, you dont need macro for library call! loading the address base is too mutch
typing for you so you go make a macro!
 You only argumant stand on nothing, if yes show me something that will 
convice me! you havent so fare.
 Last thing:-): What is 'if it's needed' (optimizing) thing? you fell that
even if codes could run 4 time faster by replacing that rouitne you want
do it because the program dont need that speed?!
 That make me Sick! you CPU has limits and when you are making it do things
it dont need to be executed a task is waiting for it!
 Anyway C do worst than that:-) I simply act that way when people think
they monopolize the CPU.
 On a C64 or if you dissable multytaking I would agree with your *effeciency*
point, but untill we have 'cycle to burn' it's not the way to think.
 And again, you say you write faster with macro... Me I would just waist time
writing them and remenbering them!
>I can see why!

You must be the king.... (cyclope in the world of the blinds).
  I never reply that way but you argument shock (<-not ed, no ended yet:-)
Anyway, hope you forgive me for my writing and this message.I must make you
feel like you discovered the table of Roset:-) 
 'Stephan, It look like script, it read like script... But it's not script!'
  :My French Teacher.

randy@jato.Jpl.Nasa.Gov (Randy Hammock) (06/12/89)

It has been my experience that a good set of macros (in any language) has
a tendency to make code more readable and easier to understand.  A project
that I worked on a few years ago had a set of "structuring" macro for our
assembler.  Can you imagine writing jump-less assembler code.  True, the
macros instered the jumps for you but you did not have think up all the
silly label name every time you had to jump around a couple of lines of
code.  We had macros that provided: loop-until, loop-while, select-case,
doif-andif-elseif.  They could even be nested 10 deep!  Remeber, if used
improperly, macros can also obfuscate code, too.

-- 
      /// |   randy@jato.jpl.nasa.gov  Telos - Jet Propulsion Laboratory - NASA
AMIGA///  | hammock@mars.jpl.nasa.gov  ** Voyager II at Neptune August 1989 **
 \\\///   |--------------------------------------------------------------------
  \XX/    | "If I wanted your opinions, I'd have given them to you!" - Mock