.macro  in assembly language

Assembly languages typically have a macro feature. A macro is a (few) lines of code with "fill-in" formal parameters (or arguments). In this sense, it is similar to a function. However, while a function is assembled once, and then may be called from many different locations, with varying arguments, a "macro call" (line containing the macro name) causes the assembler to copy the lines of the macro into the code at that point, putting in the actual arguments. This avoids the overhead of the call and return instructions, the associated argument passing, and register shuffling.

James Larus' article (pdf) describes macros for MIPS, however, his SPIM only implements a subset of the assembly language, that doesn't include macros. Mars has recently included macros, so you can use them, however that leaves me with a problem, because mipsmark relies on spim. So we need a preprocessor to do the macro expansion. I have written one, in python.

Thus, you are now free to use (Mars style) .macro and .include directives in your mips assembler code. You can run you programs with Mars, or use my "mapp" preprocessor (Macro (or Mars) Assembly PreProcessor).

The Mars .macro, .include

.include  "somefile"
includes all the lines of somefile (in your current directory) as though they were written in your program. This would be a good way to include some generally useful macros.

.macro  swap  (%a, %b)
--- for example, introduces a macro named swap, with two parameters. Then follow lines of assembly, in which %a and %b will be replaced whenever the macro is "called"
.end_macro    ends the macro
However, the ( ,  and )  are optional, to make it look like C, so please leave them out, and just use spaces, like this:

.macro  swap  %a  %b
My mapp uses a simple split() method, which splits on "whitespace"  Mars also allows $ instead of %, mapp doesn't care, but I recommend using  %  for clairity,  and lest "load a number" be transformed into "lo$spd $sp number"

swap  $t0  $t1
later on will insert the assembly instructions for swapping the values in 2 memory locations pointed to by $t0 and $t1

Restrictions for mapp

Please name your file with macros with .am, for example, myfile.am
mapp myfile
will create a file named myfile.a
Use this created file for QtSpim, spim, mipsmark, and submit cs216.
Always make your changes to myfile.am and then rerun mapp

An example of macros in Mars and mapp for SPIM

A file with macros, to be included, and a file using them, mymacros :
# macros for mips, by Lin Jensen
.macro push %reg
sub $sp, $sp,4
sw %reg, ($sp) # push %reg
.end_macro
.macro pop %reg
lw %reg, ($sp) # pop %reg
add $sp, $sp,4
.end_macro
macro.am
# testing of macros: SPIM & Mars 4.3 
.include "mymacros"
.macro done
li $v0,10
syscall #ciao
.end_macro
.macro write %string
.data
alabel: .asciiz %string
.text
la, $a0, alabel
li $v0,4
syscall
.end_macro

.globl __start
.text
__start:
li $a0, 42 # important number
push $a0
la $a0,hello
li $v0,4
syscall
pop $a0
li $v0,1 #print int
syscall
write ", freedom is slavery\n"
done
.data
hello: .asciiz "hello world\n"

These give this result:

From running the command mapp macro
This is the resulting file, macro.a which spim can execute.
# testing of macros: SPIM & Mars 4.3 
# .include "mymacros"
# macros for mips, by Lin Jensen
#---- end .include
.globl __start
.text
__start:
li $a0, 42 # important number
#mac push $a0
sub $sp, $sp,4
sw $a0, ($sp) # push $a0
#endm
la $a0,hello
li $v0,4
syscall
#mac pop $a0
lw $a0, ($sp) # pop $a0
add $sp, $sp,4
#endm
li $v0,1 #print int
syscall
#mac write ", freedom is slavery\n"
.data
alabel_16: .asciiz ", freedom is slavery\n"
.text
la, $a0, alabel_16
li $v0,4
syscall
#endm
#mac done blah
li $v0,10
syscall #ciao
#endm
.data
hello: .asciiz "hello world\n"

Mars (version 4.3 and up) will run macro.am directly, so it won't produce this file, but the code in the execute window will be the same. Mars gives the same results from either file.


Back to CS 216, or current Lab