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).
.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
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
# macros for mips, by Lin Jensenmacro.am
.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
# 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"
# 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.