next up previous
Next: 8 The ISEM Graphics Up: A Laboratory Manual for Previous: 6 Assembler DirectivesAssembler

7 Operand Sizes and Unsigned Values

 

7.1 Goal

To complete our coverage of the load and store instructions provided by the SPARC and to cover a collection of useful synthetic operations.

7.2 Objectives

After completing this lab, you will be able to write assembly language programs that use:

7.3 Discussion

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.

7.3.1 Operand sizes

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.

   table1657
Table 7.1: Operand sizes for the data transfer operations

Assembler directives

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.

   table1669
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.


Example:   Consider the following C declarations. Assuming that a character is one byte, a short integer is two bytes, and an integer is four bytes, give assembler directives to allocate and initialize the memory specified by these 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 load and store operations

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.

   table1688
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.

   table1697
Table 7.4: The load and store instructions


Example:   Rewrite the code presented in Example 6.3 using an array of 20 bytes (i.e., chars) instead of words. (You should still store the sum in a word.)

        .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


7.3.2 Unsigned operands

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.

   table1779
Table 7.5: The unsigned load operations

7.3.3 Useful (synthetic) 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.

   table1804
Table 7.6: Some useful operations


Example:   Rewrite the code presented in Example 6.3 using the operations defined in Table 7.6.

        .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


7.4 Summary

7.5 Review Questions

  1. Explain why the SPARC does not provide unsigned store operations.

7.6 Exercises

  1. Suppose that the SPARC did not have a load unsigned byte operation, explain how you could implement this operation using the load byte operation (recall, this operation always sign extends the value being loaded). Note, the Intel i860 processor provides a load byte operation but does not provide a load unsigned byte operation.


next up previous
Next: 8 The ISEM Graphics Up: A Laboratory Manual for Previous: 6 Assembler DirectivesAssembler

Barney Maccabe
Mon Sep 2 20:51:56 MDT 1996