To introduce the fundamentals of assembly language programming.
After completing this lab, you will be able to write assembly language programs that use:
In this lab we introduce the fundamentals of SPARC assembly language programming. In particular, we consider basic assembler directives, register naming conventions, the (synthetic) load and store operations, the integer addition and subtraction operations, and the (synthetic) register copy and register set operations. We begin by considering the structure of assembly language programs.
Assembly language programs are line-oriented. That is, the assembler translates an assembly language program one line at a time. The assembler recognizes four types of lines: empty lines, label definition lines, directive lines, and instruction lines.
Every line can conclude with a comment. Comments begin with the character ``!''. Whenever it encounters a ``!'', the assembler ignores the ``!'' and the remaining characters on the line.
In this lab we introduce three directives: .data, .text, and .word. The first two (.data and .text) are used to separate variable declarations and assembly language instructions. The .word directive is used to allocate and initialize space for a variable.
Each group of variable declarations should be preceded by a .data directive. Each group of assembly language instructions should be preceded by a .text directive. Using these directives, you could mix variable declarations and assembly language instructions; however, for the present, your assembly language programs should consist of a group of variable declarations followed by a group of assembly language instructions.
A variable declaration starts with a label definition (the name of the variable), followed by a .word directive, followed by the initial value for the variable. The assembler supports a fairly flexible syntax for specifying the initial value. For now, we will use simple integer values to initialize our variables. By default, the assembler assumes that numbers are expressed using decimal notation. You can use hexadecimal notation if you use the ``0x'' prefix. Example 2.1 illustrates a group of variable declarations.
.data ! start a group of variable declarations x: .word 23 ! int x = 23; y: .word 0x3fce ! int y = 0x3fce; z: .word 42 ! int z = 42;
In an assembly language program, a label is simply a name for an address. For example, given the declarations shown in Example 2.1, ``x'' is a name for the address of a memory location that was initialized to 23. On the SPARC an address is a 32-bit value. As such, labels are 32-bit values when they are used in assembly language programs.
The SPARC integer unit provides thirty-two general purpose registers. Each integer register holds 32-bits. The integer registers are called %r0 through %r31. In addition to the names %r0 through %r31, the integer registers have alternate names (aliases) as shown in Table 2.1.
Table 2.1: Aliases for the integer registers
The letter used in each group of aliases (g, o, l, or i) denotes the name for the group of registers. The group names are related to procedure calling conventions. We will discuss the meanings of these group names when we consider register windows in Lab 11. In the meantime, we will use the %r names in our assembly language programs. As you may have noted, ISEM uses the alternate names when it reports the contents of the registers and when it shows the next instruction to execute.
The value stored in %r0 is always zero and cannot be altered. If an instruction specifies %r0 is used as the destination, the result is simply discarded. It is not an error to execute an instruction that specifies %r0 as the destination for the result; however, the contents of %r0 will not be altered when this instruction is executed.
The set operation can be used to load a 32-bit signed integer constant into a register. Every set instruction has two operands: the 32-bit value followed by the destination register. Table 2.2 summarizes the set operation.
set 0x42, %r2 set x, %r3
The SPARC is based on the load/store architecture. This means that registers are used as the operands for all data manipulation operations. The operands for these operations cannot be in memory locations. Table 2.3 summarizes simple versions of the load and store operations. (We will cover these operations in more detail in later labs.)
Table 2.3: The load and store operations
The SPARC uses 2's complement representation for signed integer values. Signed additions and subtractions are performed using 32-bit arithmetic (the source and destination values are 32 bits).
Table 2.4 summarizes the signed addition and subtraction operations provided by the SPARC. The SPARC provides two instruction formats for each of the arithmetic operations. Both formats use three explicit operands--two source operands, and a destination operand. In the first format both of the source operands are in registers. In the second format, one of the source operands is in a register while the other is a small constant value. This constant value may be negative or positive; however, its 2's complement representation must fit in 13 bits. Example 2.3 presents a SPARC assembly language program that illustrates variable declarations and the operations (load, store, add, and sub) that we have described in this lab.
Table 2.4: The addition and subtraction operations
Programs to be run in the ISEM environment should terminate their execution by executing the instruction ``ta 0''. Whenever this instruction is executed, ISEM will stop executing instructions and print the message ``Program exited normally''.
.data a: .word 0x42 b: .word 0x43 c: .word 0x44 d: .word 0x45.text start: set a, %r1 ld [%r1], %r2 ! $a$ --> %r2 set b, %r1 ld [%r1], %r3 ! $b$ --> %r3 set c, %r1 ld [%r1], %r4 ! $c$ --> %r4 set d, %r1 ld [%r1], %r5 ! $d$ --> %r5
add %r2, %r3, %r2 ! $a+b$ --> %r2 sub %r4, %r5, %r3 ! $c-d$ --> %r3 sub %r2, %r3, %r2 ! $(a+b)-(c-d)$ --> %r2 set a, %r1 st %r2, [%r1] ! $(a+b)-(c-d)$ --> a
end: ta 0
We conclude this lab by considering another (synthetic) operation: mov. The mov operation is used to copy the value stored in one register to another register. This operation can also be used to load a small integer value into a register. Table 2.5 summarizes the mov operations.
Table 2.5: The register copy and register set operations
Because you can always use the set operation to load a 13-bit value to an integer register, the second version of the mov operation is redundant for integer registers. However, as we will discuss, this version of the mov operation is used to load the other state registers on the SPARC.
In this lab we have introduced the basics of SPARC assembly language programming. We began by considering the structure of an assembly language program. We then considered the names and uses of the integer registers. We then introduced three assembler directives: .text, .data, and .word. The first two (.text and .data) are used to identify sections of an assembly language program. The last two (.data and .word) are used to declare and initialize variables. We will consider additional assembler directives in later labs. We concluded the lab by introducing six assembly language operations: set, load, store, add, sub, and mov.
Figure 2.1 provides a graphical illustration for several of the operations that we have introduced in this lab. In particular, this figure illustrates the data paths used in the load, store, addition, and subtraction operations.
Figure 2.1: Illustrating the load, store, add, and subtract operations
The set and mov operations are synthetic (or pseudo) operations. That is, these operations are not really SPARC operations. Instead, the assembler translates these operations into one or more SPARC operations when it assembles your program. We will consider synthetic operations in Lab 9