To complete our coverage of the load and store instructions provided by the SPARC and to cover a collection of useful synthetic operations.
After completing this lab, you will be able to write assembly language programs that use:
In this lab we introduce the assembler directives and operations associated with different sized operands and unsigned operands. We begin by considering the operand sizes supported by the SPARC. Then we consider assembler directives used to allocate different amounts of memory. Next, we consider the load and store operations for different sized operations. The we consider the load operations for unsigned operands. Finally, we conclude by considering a small collection of useful synthetic operations.
On the SPARC, all data manipulation operations (e.g., integer addition and integer subtraction) manipulate 32-bit values. However, the data transfer operations (e.g., load and store) can transfer different sized values between the memory and the integer registers. Table 7.1 summarizes the operand sizes supported by the SPARC load and store operations.
Table 7.1: Operand sizes for the data transfer operations
The .word directive introduced in Lab 2 allocates and initializes memory in 32-bit (word) units. Table 7.2 summarizes the assembler directives for allocating and initializing different sized units of memory. The name of the directive used to allocate and initialize a 64 bit doubleword, ``.quad'', is historical. The name dates to a time when words were 16 bits. Quad is short for quad-word, that is, four 16-bit words.
Table 7.2: Directives for allocating and initializing memory
The SPARC load and store operations require that halfword values be aligned on even addresses (i.e., halfword alignment) and that word and double word values be aligned on addresses that are a multiple of four (i.e., word aligned). You can use the .align directive to make sure that your variables are aligned as needed. This directive takes a two arguments, a number and an optional pad value. When the assembler encounters an align directive, it makes sure that the next address in the current assembler segment is a multiple of the first argument. For example, the directive ``.align 8'' will ensure that the next address is a multiple of 8. To ensure that the next address meets the alignment requirements, the assembler emits ``pad'' bytes. If the second argument is supplied, the assembler uses this value when it emits pad bytes; otherwise, the assembler emits zeros. Example 7.1 illustrates the size and alignment directives.
short int short1 = 22; char ch1 = 'a'; short int short2 = 33; char ch2 = 'A'; int int1 = 0;
.data .align 2 ! halfword align short1: .hword 22 ! allocate and initialize a halfword ch1: .byte 'a' ! allocate and initialize a byte .align 2 ! halfword align short2: .hword 33 ! allocate and initialize a second halfword ch2: .byte 'A' ! allocate and initialize a second byte .align 4 ! word align int1: .word 0 ! allocate and initialize a word
The size of the operand for a load or store operation is specified using a suffix: ``d'' for doubleword, ``h'' for halfword, or ``b'' byte. The operation names are summarized in Table 7.3.
Table 7.3: The load and store operations
The load operations take two operands: the (source) memory address followed by the (destination) register. Similarly, the store operations take two operands: the (source) register followed by the (destination) memory address.
The load byte, halfword, and word operations set all 32 bits of the destination register. The load byte operation (ldb) fetches an 8-bit value, sign extends this value to 32 bits, and loads the resulting value into destination register. The load halfword operation (ldh) fetches a 16-bit value and sign extends this value to 32 bits. The load word operation (load) fetches a 32-bit value and load this value into the destination register. The load doubleword operation fetches two 32-bit values and loads them into consecutive registers--starting with the register specified in the instruction (e.g., %r2 and %r3).
The store byte operation (stb) stores the least significant 8 bits of the source register to the destination memory location. The store halfword operation (sth) stores the least significant 16 bits of the source register into the destination memory location. The store word operation (st) stores the contents of a register to the destination memory address. The store doubleword operation (stored) stores the contents two consecutive registers (starting with the register specified in the instruction).
The memory addresses used with the operations that load and store halfwords must be even (i.e., halfword aligned). The memory addresses used with the operations that load and store words and doublewords must be multiples of four (i.e., word aligned). The register used with the operations that load and store doublewords must be even (e.g., %r2 but not %r3). When these operations are used, the most significant 32 bits are stored in the even register.
Table 7.4: The load and store instructions
.data arr: .skip 20 ! allocate an array of 20 bytes sum: .word 0 ! allocate a word to hold the sum.text start: set arr, %r2 ! %r2 is the base address mov %r0, %r3 ! %r3 is the index value mov %r0, %r4 ! %r4 is the running sum set 20, %r5 ! %r5 is the number of elems to add
loop: ldb [%r2+%r3], %r6 ! fetch the next element add %r4, %r6, %r4 ! add it to the running sum subcc %r5, 1, %r5 ! one fewer element bne loop ! if %r5 > 0 get next element add %r3, 4, %r3 ! increment the index (DELAY SLOT)
sethi %hi(sum), %r1 ! store the result in sum st %r4, [%r1+%lo(sum)] end: ta 0
The SPARC instruction set also provides a load unsigned byte operation (loadub) and a load unsigned halfword operation (loaduh). In contrast to the standard load operations (loadb and loadh), these operations do not sign extend their values. They always set the most significant bits to zero.
Table 7.5: The unsigned load operations
We conclude this lab by considering a collection of useful operations. In particular, we consider the (synthetic) operations clear, negate, increment, and decrement. These operations are summarized in Table 7.6.
Table 7.6: Some useful operations
.data arr: .skip 20*4 ! allocate an array of 20 words sum: .word 0 ! allocate a word to hold the sum.text start: set arr, %r2 ! %r2 is the base address clr %r3 ! %r3 is the index value clr %r4 ! %r4 is the running sum set 20, %r5 ! %r5 is the number of elems to add
loop: ld [%r2+%r3], %r6 ! fetch the next element add %r4, %r6, %r4 ! add it to the running sum deccc %r5 ! one fewer element bne loop ! if %r5 > 0 get next element inc 4, %r3 ! increment the index (DELAY SLOT)
sethi %hi(sum), %r1 ! store the result in sum st %r4, [%r1+%lo(sum)] end: ta 0