home *** CD-ROM | disk | FTP | other *** search
/ Falcon 030 Power 2 / F030_POWER2.iso / ST_STE / MAGS / ICTARI09.ARJ / ictari.09 / ASSEMBLY / MACROS / MACROTUT.TXT
Text File  |  1994-04-17  |  20KB  |  409 lines

  1.  
  2.                        ASSEMBLER MACRO TUTORIAL (DEVPAC)
  3.                        =================================
  4.  
  5.                         By Peter Hibbs and Simon Rigby
  6.  
  7.     An assembler MACRO definition is a system for equating a single word to
  8.     a group of machine code  instructions  which  can  then  be used in the
  9.     program source code. The main object  of  MACROs  is to make the source
  10.     code easier to read and also easier  to program. Used with care, MACROs
  11.     can be a great help to the  programmer although there are some pitfalls
  12.     which should be  avoided.  Usually  (but  not  always)  the  MACROs are
  13.     defined in a separate file  and  'included'  in the main program source
  14.     code  which  avoids  cluttering  up   the   source  file.  Since  MACRO
  15.     definitions must be defined  BEFORE  they  are  used  in a program, the
  16.     MACRO file must be included near the beginning of the source file.
  17.  
  18.     This tutorial refers  entirely  to  HiSofts  Devpac assembler. Although
  19.     most modern assemblers can use MACROs  there may be some differences in
  20.     the details, refer to your assembler manual for further information.
  21.  
  22.     MACRO FORMAT
  23.     ¯¯¯¯¯¯¯¯¯¯¯¯
  24.     To define a MACRO a label is used  which is the name given to the MACRO
  25.     followed by the machine code  instructions  and  the ENDM command which
  26.     terminates the MACRO definition. A simple  example is shown below which
  27.     executes a TOS call to wait for the next vertical sync pulse.
  28.  
  29.     v_sync         MACRO
  30.                    movem.l   d0-d2/a0-a2,-(sp)   save registers
  31.                    move      #37,-(sp)           function 37
  32.                    trap      #14                 call TOS trap 14
  33.                    addq.l    #2,sp               correct stack
  34.                    movem.l   (sp)+,d0-d2/a0-a2   restore registers
  35.                    ENDM
  36.  
  37.     In the user program the word  v_sync  is  used in the instruction field
  38.     wherever the above sequence of instructions is required. For example :-
  39.  
  40.  
  41.                    move      #24,d0              load register
  42.     loop           v_sync                        execute macro
  43.                    dbra      d0,loop             repeat 23 times
  44.                    ..
  45.  
  46.     In the MACRO  definition  the  words  MACRO  and  ENDM  are  written in
  47.     capitals, this is not necessary but  is  usually  done to make the code
  48.     easier to understand. Note that in  this example the registers that are
  49.     (or may be) used by the trap  call  are saved at the start and restored
  50.     at the end. However, in all  HiSofts  MACROs and in the TOSMACRO.S file
  51.     which accompanies this document, this is  not the case. This highlights
  52.     an important point concerning  MACRO  definition files especially where
  53.     there are a large number in one file, that is that all MACROs should be
  54.     properly documented so  that  the  programmer  knows  exactly what each
  55.     MACRO does, the parameters  which  need  to  be  passed  to  it and any
  56.     parameters returned. If this is not done  properly a lot of time can be
  57.     wasted trying to sort out why the MACRO code doesn't work especially as
  58.     the MACRO code itself could be in another file hidden away somewhere on
  59.     the disk. A text file should be  written  and printed out with the name
  60.     of each MACRO and its required parameters and kept as a quick reference
  61.     guide.
  62.  
  63.     MACRO SIZE
  64.     ¯¯¯¯¯¯¯¯¯¯
  65.     A mistake that is easy to make is to overdo the MACRO size. It is not a
  66.     good idea to make a MACRO too  large,  say  more than about 10 lines of
  67.     code. Don't forget that wherever the MACRO is used, all the code in the
  68.     MACRO will be inserted into the object  code. If a MACRO is used dozens
  69.     of times in a program the  source  code  file  will still look nice and
  70.     small but the object code will be much larger than it needs to be. Also
  71.     debugging a program is  more  difficult,  for  example  if  you need to
  72.     single step through a section of code which has several large MACROs it
  73.     can lead to more wasted time since the chances are the MACRO code works
  74.     OK as it has probably been  tested  elsewhere. For large blocks of code
  75.     which are called repeatedly, a normal sub-routine should be used. Also,
  76.     with HiSofts debugger, a sub-routine can  be executed without having to
  77.     single step through it  which  you  cannot  do  with  a MACRO. The sub-
  78.     routine call itself could  still  be  made  into  a MACRO, if required,
  79.     although this is a bit pointless.
  80.  
  81.     BLACK BOX THEORY
  82.     ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
  83.     Ideally all commonly used  sub-routines  should  be  made  into a Macro
  84.     file, as later changes in the way data is passed to the sub-routine, or
  85.     additions to the number of parameters  can  be  catered for in a macro,
  86.     but would have to involve changing all your old program code (or making
  87.     a new subroutine with a different name) otherwise.
  88.  
  89.     A case in point is Fsel_input which  now  has two GEM calls, one with a
  90.     title and one without. The macro could  be  made to count the number of
  91.     parameters passed and decide which one to use.
  92.  
  93.     PASSING PARAMETERS TO MACROs
  94.     ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
  95.     It is often required to  pass  parameters  to  some of the instructions
  96.     within the MACRO  definition.  Since  these  are  not  always  known at
  97.     assembly time there is a  system  for  passing  parameters to the MACRO
  98.     during program execution. A common  type  of  MACRO are the various TOS
  99.     calls using the GEMDOS,  BIOS  and  XBIOS  some  of which require other
  100.     variables when used. For example,  the  GEMDOS call #2 (c_conout) which
  101.     outputs a  character  to  the  screen  requires  the  character  to  be
  102.     displayed to be pushed onto the  stack  when  called. This value can be
  103.     passed to the MACRO as a constant,  in  a register or in a memory store
  104.     when the program is run.  It  is  defined  in  the  MACRO itself as a \
  105.     character followed by an alpha-numeric  character  1-9, a-z or A-Z. For
  106.     example the c_conout MACRO could be defined as :-
  107.  
  108.     c_conout       MACRO               \1=character
  109.                    move      \1,-(sp)  push chr onto stack
  110.                    move      #2,-(sp)  function No
  111.                    trap      #1        GEMDOS call
  112.                    addq.l    #4,sp     correct stack
  113.                    ENDM
  114.  
  115.     In the program source code the MACRO would be called like this :-
  116.  
  117.                    c_conout  #'A'
  118.  
  119.     and would display the character A.  The  \1  value is replaced with the
  120.     data following the MACRO call. This  value  can be a constant (preceded
  121.     by a # character),  a  register  (d0-d7  or  a0-a6)  or  a memory store
  122.     without changing the MACRO itself. For example the following two MACROs
  123.     both do the same thing as the one above :-
  124.  
  125.                    move      #'A',d0
  126.                    c_conout  d0
  127.  
  128.     or
  129.  
  130.                    move      #'A',store
  131.                    c_conout  store
  132.                    ..
  133.     store          ds.w      1
  134.  
  135.     The assembler automatically works out  what  format the parameter is in
  136.     and generates the object code accordingly.  Up  to 36 parameters can be
  137.     passed to  a  MACRO,  subsequent  parameters  should  follow  the first
  138.     separated by commas. MACROs can also be  nested as shown in the example
  139.     below :-
  140.  
  141.  
  142.     gemdos         MACRO               1\function,2\stack size
  143.                    move      \1,-(sp)  push function number to stack
  144.                    trap      #1        execute
  145.                    add       \2,sp     correct stack
  146.                    ENDM
  147.  
  148.  
  149.     f_read         MACRO               1\buffer,2\count,3\fhandle
  150.                    move.l    \1,-(sp)  push buffer address to stack
  151.                    move.l    \2,-(sp)  push count value to stack
  152.                    move      \3,-(sp)  push file handle to stack
  153.                    gemdos    #63,#12   execute GEMDOS MACRO call 63
  154.                    ENDM
  155.  
  156.     The first MACRO (gemdos) takes two  parameters, the function number and
  157.     the stack correction value  which  is  then  used  by  the second MACRO
  158.     (f_read). So when the f_read MACRO is invoked as :-
  159.  
  160.                    move.l    #2000,d0
  161.                    f_read    #file_buff,d0,fhandle
  162.  
  163.     the code would be expanded to :-
  164.  
  165.                    move.l    #file_buff,-(sp)
  166.                    move.l    d0,-(sp)
  167.                    move      fhandle,-(sp)
  168.                    move      #63,-(sp)
  169.                    trap      #1
  170.                    add.l     #12,sp
  171.                    ..
  172.     fhandle        ds.w      1                   file handle
  173.     file_buff      ds.b      2000                file buffer
  174.  
  175.     Note that it is not necessary  to  define  the value sizes in the MACRO
  176.     call as this is done in  the  MACRO  definition itself although it is a
  177.     good idea to specify the size in  the  document file to remind the user
  178.     what size parameter is required. The # character is necessary for fixed
  179.     values or addresses but not for  registers  or the contents of a memory
  180.     store. Note also that  the  names  shown  on  the  line after the MACRO
  181.     pseudo-op are comments to  remind  the  programmer which parameters are
  182.     being used within the MACRO.
  183.  
  184.  
  185.     NEW INSTRUCTIONS
  186.     ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
  187.     One trivial use for MACROs is to  invent new instructions for the 68000
  188.     CPU.  On some  processors there  are  bit instructions BZ and BNZ which
  189.     branch if  a  bit  value  is  zero  or  non-zero.  Although  there  are
  190.     equivalents on the 68000 (beq and bne) they are not so obvious. The two
  191.     MACROs below allow the use of 'bz' if a bit = 0 and 'bnz' if a bit <> 0
  192.     without increasing the number of instructions in the object code.
  193.  
  194.     bz             MACRO
  195.                    beq       \1
  196.                    ENDM
  197.  
  198.     bnz            MACRO
  199.                    bne       \1
  200.                    ENDM
  201.  
  202.     In the source code the instructions would be used in the normal way :-
  203.  
  204.                    btst      #1,d0     test bit 1 in reg d0
  205.                    bz        address   branch if bit=0
  206.  
  207.     or
  208.  
  209.                    btst      #0,flags  test bit 0 in (flags)
  210.                    bnz       address   branch if bit<>0
  211.  
  212.  
  213.     TESTING PARAMETERS
  214.     ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
  215.     When a MACRO requires  parameters  the  programmer  usually enters them
  216.     into the code, however the MACRO itself can test whether a parameter is
  217.     missing and generate an assembly error to warn that something is wrong.
  218.     In the example above the MACRO  can  test  whether the address has been
  219.     provided after the bz or bnz instruction. For example :-
  220.  
  221.     bz             MACRO
  222.                    IFC       '','\1'   test for missing parameter
  223.                    FAIL                generate error
  224.                    MEXIT               exit macro prematurely
  225.                    ENDC                end of IF
  226.                    beq       \1
  227.                    ENDM
  228.  
  229.  
  230.     The MACRO first checks if there is a string as a parameter and skips to
  231.     the ENDC pseudo-op if there is.  If  there  is no address parameter the
  232.     FAIL pseudo-op generates an  assembly  error  and  then exits the MACRO
  233.     with the MEXIT pseudo-op.  If  the  MEXIT  command  is not included the
  234.     assembler generates another error when it gets to the 'beq' instruction
  235.     because of the missing address label. The line with the FAIL command is
  236.     stored in the  error  file  but  the  cursor  is  positioned  on the bz
  237.     instruction in the source file.
  238.  
  239.     NUMBER OF ARGUMENTS
  240.     ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
  241.     It is sometimes necessary for a  MACRO  to know how many arguments have
  242.     been passed to it  from  the  main  program.  The  NARG reserved symbol
  243.     defines the number of arguments actually following a MACRO call and can
  244.     be used within the MACRO  using  the  IF  pseudo-ops. One example is to
  245.     check whether the correct number of  arguments have been defined in the
  246.     MACRO call.  In  the  example  below  the  rsconf  MACRO  requires  six
  247.     arguments which means that the NARG  symbol  will have the value six if
  248.     all the arguments have been entered  after  the MACRO call, by checking
  249.     that this value is six within the  MACRO, the assembler can generate an
  250.     error if it is incorrect. The MACRO definition would be as follows :-
  251.  
  252.     rsconf         MACRO              1\scr,2\tsr,3\rsr,4\ucr,5\ctrl,6\baud
  253.                    IFNE      6-NARG   if 6-NARG NotEqual to zero
  254.                    FAIL      Invalid parameters
  255.                    MEXIT               exit MACRO
  256.                    ENDC
  257.                    move      \1,-(sp)
  258.                    move      \2,-(sp)
  259.                    move      \3,-(sp)
  260.                    move      \4,-(sp)
  261.                    move      \5,-(sp)
  262.                    move      \6,-(sp)
  263.                    move      #15,-(sp)
  264.                    trap      #14
  265.                    add       #14,sp
  266.                    ENDM
  267.  
  268.     If less than (or more than) six  parameters  are used in the MACRO call
  269.     the assembler will flag an error  during assembly. Note that the symbol
  270.     \# can also be used in place of the NARG symbol.
  271.  
  272.     INSTRUCTION SIZE
  273.     ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
  274.     The symbol \0 can also  be  used  to  indicate an instruction size i.e.
  275.     byte, word or longword. The following  example (from the DevPac manual)
  276.     illustrates this. An INC or DEC  instruction can be easily simulated on
  277.     the 68000 CPU with the following MACRO :-
  278.  
  279.     inc            MACRO               1\register
  280.                    addq.\0   #1,\1     add 1 to register
  281.                    ENDM
  282.  
  283.     In the source code the instructions would be formed as :-
  284.  
  285.                    inc.b     d0        increment low byte
  286.  
  287.     or             inc.w     d1        increment low word
  288.  
  289.     or             inc.l     a0        increment whole register
  290.  
  291.     The \0 symbol passes the size of the  register to the MACRO so that the
  292.     correct part of the register is  incremented.  Note  that if no size is
  293.     provided the instruction defaults to .w  (16 bits). The dec instruction
  294.     will be the same except the addq will be subq.
  295.  
  296.     MACRO LABELS
  297.     ¯¯¯¯¯¯¯¯¯¯¯¯
  298.     It is sometimes useful to have a  branch (or jump) instruction within a
  299.     more complicated MACRO. It is  not  possible,  however, to use a normal
  300.     label because if the MACRO is  used  more  than once the assembler will
  301.     see duplicate label symbols. The \@  symbol  provides a method of using
  302.     MACRO labels, the assembler  generates  a  different  unique label each
  303.     time the MACRO is used. The example below shows this technique :-
  304.  
  305.     clr_screen     MACRO
  306.                    move.l    screen,a0           fetch screen address
  307.                    move      #32000/4-1,d0       set loop counter
  308.     \@             clr.l     (a0)+               clear word and inc
  309.                    dbra      d0,\@               dec count and repeat
  310.                    ENDM
  311.  
  312.     Another example using both of the above symbols is a Memory Move, where
  313.     you can move bytes, words or longs  and it shows how MACROS can improve
  314.     efficiency at the same time...
  315.  
  316.     Move block of memory in bytes, words or longs, uses registers d0/a0-a1
  317.  
  318.     Mem_move       MACRO     from,to,count (in bytes,words or longs)
  319.                    move.w    \3,d0
  320.                    move.l    \1,a0
  321.                    move.l    \2,a1
  322.     .\@            move.\0   (a0)+,(a1)+
  323.                    dbra      d0,.\@
  324.                    ENDM
  325.  
  326.     and in the program use one of the following :-
  327.  
  328.          Mem_move.b          from_addr,to_addr,number_of_bytes
  329.          Mem_move.w          from_addr,to_addr,number_of_words
  330.          Mem_move.l          from_addr,to_addr,number_of_longs
  331.  
  332.     Note also that the 'full  stop'  character  can  be  used  as part of a
  333.     label.
  334.  
  335.     MACRO TABLE
  336.     ¯¯¯¯¯¯¯¯¯¯¯
  337.     The MACRO symbol definitions  are  stored  in  a  separate table to the
  338.     normal source code symbols  so  that  MACRO  names  can  be the same as
  339.     labels without causing the assembler to  flag  up an error. For example
  340.     the following sub-routine is valid if a little confusing :-
  341.  
  342.  
  343.     v_sync         movem.l   d0-d2/a0-a2,-(sp)   save registers
  344.                    v_sync                        call macro
  345.                    movem.l   (sp)+,d0-d2/a0-a2   restore registers
  346.                    rts
  347.  
  348.     OTHER SYMBOLS
  349.     ¯¯¯¯¯¯¯¯¯¯¯¯¯
  350.     There are a few more symbols associated with MACROs which are described
  351.     in the DevPac manual but as  they  are  not  used  very much I have not
  352.     mentioned them in this document.
  353.  
  354.     MACRO FILE DOCUMENTATION
  355.     ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
  356.     As mentioned above it is  important  to  keep  a printed document which
  357.     details the function of each  MACRO  together with any parameters which
  358.     are passed to it and any  returned.  Since  MACRO files can get changed
  359.     from time to time as more  options  are  added or bugs corrected, it is
  360.     also prudent to include the issue number and any changes that have been
  361.     made to the file. These are best  placed  at the beginning of the MACRO
  362.     file and the document file  together  with  the description and date of
  363.     each change.
  364.  
  365.     USING DEVPAC AND ICTARI MACRO FILES
  366.     ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
  367.     HiSoft supply all the standard GEM  function  calls for the AES and VDI
  368.     as a MACRO file with the DevPac assembler (GEMMACRO.I or GEMMACRO.S for
  369.     DevPac 2) together  with  the  AES  and  VDI  library  files. Since all
  370.     programmers with DevPac will have  these  files, members should use the
  371.     MACROs in any source code that is  sent  in  to ICTARI to make the code
  372.     shorter and easier to understand.
  373.  
  374.     Unfortunately HiSoft do not provide  a  MACRO  file  for the TOS system
  375.     calls so we have provided two versions  on  this disk which can be used
  376.     as a standard  MACRO  files.  The  file  TOSMACRO.S  in  folder MACRO_1
  377.     defines all the TOS calls (but not the extra ones added to the STE TOS)
  378.     in a simple  form.  The  associated  text  file  TOSMACRO.TXT shows the
  379.     format for each MACRO in the source  file.  The second MACRO file is in
  380.     the MACRO_2 folder and is  called  MACRO_V1.I  which, in turn, uses the
  381.     other .I files in the same  folder. These MACROs are more comprehensive
  382.     and include various error  checking  facilities.  There  is no separate
  383.     text file but each  MACRO  has  an  explanation  of  its use within the
  384.     source file which could be  printed  out  for reference. The programmer
  385.     can decide which one  he  wants  to  use  (or  even  use both) and copy
  386.     it/them to his  INCDIR  folder  or  wherever  the  'include'  files are
  387.     stored. We would encourage members sending in source code which use TOS
  388.     calls to use one of these MACRO  files  (don't forget to say which) and
  389.     use the appropriate MACROs in the code to make it easier to understand.
  390.  
  391.     If members send in some source  code  which  uses  a MACRO which is NOT
  392.     defined in the MACRO  files  just  mentioned  above,  would they please
  393.     include the MACRO definition in the  source  code itself or send in the
  394.     MACRO file together with the source code. Obviously any MACROs that are
  395.     used in the code are useless without the MACRO code itself.
  396.  
  397.     CONCLUSION
  398.     ¯¯¯¯¯¯¯¯¯¯
  399.     It should be  clear  from  this  article  that  MACROs  can improve the
  400.     clarity of complex assembler  source  code  providing  they are used in
  401.     moderation. It would be  possible,  for  example,  to  make every small
  402.     section of code into a MACRO  which  would  then defeat the main aim of
  403.     using MACROs. Also, creating standard MACRO files which all programmers
  404.     can use, makes source code simpler  and  easier  to follow which is the
  405.     primary aim of a programmers user group  such as ICTARI. If any members
  406.     have any further comments to make  regarding this subject, ICTARI would
  407.     be very interested to hear them.
  408.                              ____________________
  409.