SPARC Assembly/SPARC Instructions< SPARC Assembly
Here is a quick-rundown of the arithmetic instruction format, when writing your SPARC code:
- mnemonic %rsrcA, srcB, %rdest
The instruction mnemonic (commonly, but inaccurately, also referred to as the "opcode") specifies the type of operation to be performed. rsrcA is the first operand, while srcB is the second. rsrcA must be a register, and srcB can usually be a signed immediate (13 bit) constant or a second register. rdest is the destination register, and not all instructions have one (for example: cmp for compare).
Note that in SPARC assembly language, instructions always read from left to right. The left (and middle, if present) operands are source operands. If the operation writes a result anywhere (as almost all operations do), the result is written to the rightmost operand (destination register or destination memory location).
In SPARC assembly language, the following instructions are completely valid:
add %r3, %r4, %r5
add %r3, 16, %r5
- The first instruction adds register 3 and register 4, and places the result in register 5.
- The second instruction adds register 3, and the number 16, and places the result in register 5.
As you can see, SPARC assembly places a % sign before each register name, while numeric literals are written normally.
Warning: This syntax is backwards from Intel syntax (used in PPC chips, and some compilers).
It should also be noted that many SPARC instructions such as the logic and arithmetic instructions have a version of each instruction with "cc" appended to the end of the mnemonic. These instructions perform the same function as their non-"cc" counterpart, but also set condition codes (more on these later) that can be used to regulate branching within a program. For example, the "add" instruction mentioned above has a counterpart "addcc", which when performing an addition sets specific condition codes that later branch instructions check when deciding whether or not to branch to another part of the program.
Comments will not be read by the compiler, and are indicated with an exclamation point. Anything following the exclamation point on that line will be ignored. Comments help you understand what you are doing, and why you are doing it. The following is a bad example of commenting:
sub %l0, %l3, %g1 ! Subtract local register 3 from l0, and put the result in global 1. ! add %g1, %l4, %g1! We should add in local 4, but I'm not doing that yet
We can easily tell what we are doing; the code says that. The comments have told us nothing.
However this is better:
sub %l0, %l3, %g1 ! Subtract our monthly expenses from our monthly income. ! This will later be used in function _foo. ! add %g1, %l4, %g1! Local 4 will hold "other" sources of income, but we're not there yet.
Now we know what we're doing (we're figuring spare change for the month), and why we're doing it (function foo will apparently use this). Also, note that the second line in both examples will not be executed as their instructions have been commented out (apparently to be implemented later).
Do note that many people comment almost every single line of code in assembly, due to the fact that it can sometimes be difficult to tell what's going on without useful things like variable names, complex structures, etc.
Labels are indicated by placing a "label_name:" at some point in your code. As labels are just areas that give the compiler addresses, they can be used for anything that's stored directly in the program: most popularly, these are used for function jumps (via branch or call statements), or ways to reference constant variables. If it is a function, and not a jump, ".global" must be placed before it. There is one special label/global, just like every language, and that is the "main" label, which is where the program starts.
.global main main: save %sp, -64, %sp mov 5, %l0 cmp %l0, 5 be,a end ta 1 ! Should NEVER happen end: mov 1, %g1 ta 0
In this program are a bunch of things that might not be understandable, but this is a full program. It starts at the main function (defined by ".global main, followed by the label). It then copies the value "5" into a local register, and then compares that register to the value of "5". If they are equal, it branches to the label end, where the program then exits.