# 3.10: Shift Operations

- Page ID
- 28491

The final topic covered in this chapter is the shift operations. Shift allow bits to be moved around inside of a register. There are many reasons to do this, particularly when working with low level programs such as device drivers. The major reason this might be done in a HLL is to multiplication and division, but as was stated earlier, multiplication and division using constants should not be implemented by the programmer, as the compiler will automatically generate the best code for the situation. So these operations are difficult to justify in terms of higher level languages. These operations will simply be presented here with an example of multiplication and division by a constant. The reader will have to trust that these operators are useful in assembly and will be used in future chapters.

There are 2 directions of shifts, a right shift and a left shift. The right shift moves all bits in a register some specified number of spaces to the right, and the left shift moves bits some specified number of spaces to the left.

The bits that are used to fill in the spaces as the shift occurs are determined by the type of the shift. A logic shift uses zeros (0) to replace the spaces.

The arithmetic shift replaces the spaces with the high order (left most) bit. In an integer the high order bit determines the sign of the number, so shifting the high order keeps the correct sign for the number^{12}. Note that the sign only matters when doing a right shift, so only the right shift will have an arithmetic shift.

Finally there is a circular shift (called a rotate in MIPS) that shifts in the bit that was shifted out on the opposite side of the value. For example, when the 4 bit value 0011 is rotated right, a 1 is returned and this 1 is shifted into the right most bit, giving 1001. Likewise when the 4 bit value 0011 is rotated left, a 0 is returned and this 0 is shifted into the right most bit, giving 0110.

The main use of a rotate command is to allow the programmer to look at each of the 32 bits in a value one at a time, and at the end the register contains the original value. The rol and ror operators (rotate left/right) are pseudo operators, and a circular shift can be implemented using combinations of left and right logical shifts, and an OR operation. This will be explored in the questions at the end of the chapter.

The following examples show how each of these shifts work.

Shift left logical 2 spaces: 0x00000004 -> 0x0000000f Shift right logical 3 spaces: 0x0000001f -> 0x0000003 Shift right arithmetic 3 spaces: 0x0000001f -> 0x00000003 Shift right arithmetic 2 spaces: 0xffffffe1 -> 0xfffffff8 Rotate right 2 spaces: 0xffffffe1 -> 0x7ffffff8 Rotate left 2 space: 0xffffffe1 -> 0xffffff87

The program in the following section will implement each of these operations to show how they work.

The following are the shift operations provided in MIPS.

`sll`

(shift left logical) operator. The operator shifts the value in R_{t}shift amount (shamt) bits to the left, replacing the shifted bits with 0's, and storing the results in R_{d}. Note that the registers R_{d}and R_{t}are used. The numeric value in this instruction is not an immediate value, but a shift amount. Shift values are limited to the range 0..31 in all of the following instructions.format:

`sll R`

_{d}, R_{t}, shamtmeaning:

`R`

_{d}<- R_{t}<< shamt`sllv`

(shift left logical variable) operator. The operator shifts the value in R_{t}bits to the left by the number in R_{s}, replacing the shifted bits with 0's. The value in R_{s}should be limited to the range 0..31, but the instruction will run with any value.format:

`sllv R`

_{d}, R_{t}, R_{s}meaning:

`R`

_{d}<- R_{t}<< R_{s}`srl`

(shift right logical) operator. The operator shifts the value in R_{t}shift amount (shamt) bits to the right, replacing the shifted bits with 0's, and storing the results in R_{d}.format:

`srl R`

_{d}, R_{t}, shamtmeaning:

`R`

_{d}<- R_{t}>> shamt`srlv`

(shift right logical variable) operator. The operator shifts the value in R_{t}bits to the right by the number in R_{s}, replacing the shifted bits with 0's. The value in R_{s}should be limited to the range 0..31, but the instruction will run with any value.format:

`srlv R`

_{d}, R_{t}, R_{s}meaning:

`R`

_{d}<- R_{t}>> R_{s}`sra`

(shift right arithmetic) operator. The operator shifts the value in R_{t}shift amount (shamt) bits to the right, replacing the shifted bits with sign bit for the number, and storing the results in R_{d}.format:

`sra R`

_{d}, R_{t}, shamtmeaning:

`R`

_{d}<- R_{t}>> shamt`srav`

(shift right arithmetic variable) operator. The operator shifts the value in R_{t}bits to the right by the number in R_{s}, replacing the shifted bits the sign bit for the number. The value in R_{s}should be limited to the range 0..31, but the instruction will run with any value.format:

`srla R`

_{d}, R_{t}, R_{s}meaning:

`R`

_{d}<- R_{t}>> R_{s}`rol`

(rotate left) pseudo operator. The operator shifts the value in R_{t}shift amount (shamt) bits to the right, replacing the shifted bits with the bits that were shifted out, and storing the results in R_{d}.format:

`sra R`

_{d}, R_{t}, shamtmeaning:

`R`

_{d }[shamt..0] <- R_{t}[31..31-shamt+1],`R`

_{d}[31..shamt] <- R_{t}[31-shamt..0],translation:

`srl $at, $R`

_{t}, shamt`sll $R`

_{d}, $R_{t}, shamt`or $R`

_{d}, $R_{d}, $at`rolr`

(rotate fight) pseudo operator. The operator shifts the value in R_{t}shift amount (shamt) bits to the right, replacing the shifted bits with the bits that were shifted out, and storing the results in R_{d}.format:

`sra R`

_{d}, R_{t}, shamtmeaning:

`R`

_{d}[31-shamt..shamt] <- R_{t}[31..shamt],`R`

_{d}[31..31-shamt+1] <- R_{t}[shamt-1..0],translation:

`srl $at, $R`

_{t}, shamt`sll $R`

_{d}, $R_{t}, shamt`or $R`

_{d}, $R_{d}, $at

## 3.10.1 Program illustrating shift operations

The following program illustrates the shift operations from the previous section.

Program 3-6: Program illustrating shift operations # File: Program3-6.asm # Author: Charles Kann # Purpose: To illustrate various shift operations. .text .globl main main: #SLL example addi $t0, $zero, 4 sll $s0, $t0, 2 addi $v0, $zero, 4 la $a0, result1 syscall addi $v0, $zero, 1 move $a0, $s0 syscall #SRL example addi $t0, $zero, 16 srl $s0, $t0, 2 addi $v0, $zero, 4 la $a0, result2 syscall addi $v0, $zero, 1 move $a0, $s0 syscall #SRA example addi $t0, $zero, 34 sra $s0, $t0, 2 addi $v0, $zero, 4 la $a0, result3 syscall addi $v0, $zero, 1 move $a0, $s0 syscall #SRA example addi $t0, $zero, -34 sra $s0, $t0, 2 # sra 2 bits, which is division by 4 addi $v0, $zero, 4 # Output the result la $a0, result4 syscall addi $v0, $zero, 1 move $a0, $s0 syscall #rol example ori $t0, $zero, 0xffffffe1 ror $s0, $t0, 2 li $v0, 4 la $a0, result6 syscall li $v0, 34 move $a0, $s0 syscall #rol example ori $t0, $zero, 0xffffffe1 rol $s0, $t0, 2 li $v0, 4 la $a0, result6 syscall li $v0, 34 move $a0, $s0 syscall addi $v0, $zero, 10 # Exit program syscall .data result1: .asciiz "\nshift left logical 4 by 2 bits is " result2: .asciiz "\nshift right logical 16 by 2 bits is " result3: .asciiz "\nshift right arithmetic 34 by 2 bits is " result4: .asciiz "\nshift right arithmetic -34 by 2 bits is " result5: .asciiz "\nrotate right 0xffffffe1 by 2 bits is " result6: .asciiz "\nrotate left 0xffffffe1 by 2 bits is "

^{12} This is why it is in some sense incorrect to call the high order bit of an integer a "sign bit". To do division the high order (left-most) bit is replicated to the right. If this high order bit was just a sign bit, it would not be replicated, as the one sign bit only specifies the sign.