# 3.9: Using Logical Operators

$$\newcommand{\vecs}{\overset { \rightharpoonup} {\mathbf{#1}} }$$ $$\newcommand{\vecd}{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}}$$$$\newcommand{\id}{\mathrm{id}}$$ $$\newcommand{\Span}{\mathrm{span}}$$ $$\newcommand{\kernel}{\mathrm{null}\,}$$ $$\newcommand{\range}{\mathrm{range}\,}$$ $$\newcommand{\RealPart}{\mathrm{Re}}$$ $$\newcommand{\ImaginaryPart}{\mathrm{Im}}$$ $$\newcommand{\Argument}{\mathrm{Arg}}$$ $$\newcommand{\norm}{\| #1 \|}$$ $$\newcommand{\inner}{\langle #1, #2 \rangle}$$ $$\newcommand{\Span}{\mathrm{span}}$$ $$\newcommand{\id}{\mathrm{id}}$$ $$\newcommand{\Span}{\mathrm{span}}$$ $$\newcommand{\kernel}{\mathrm{null}\,}$$ $$\newcommand{\range}{\mathrm{range}\,}$$ $$\newcommand{\RealPart}{\mathrm{Re}}$$ $$\newcommand{\ImaginaryPart}{\mathrm{Im}}$$ $$\newcommand{\Argument}{\mathrm{Arg}}$$ $$\newcommand{\norm}{\| #1 \|}$$ $$\newcommand{\inner}{\langle #1, #2 \rangle}$$ $$\newcommand{\Span}{\mathrm{span}}$$

Most students have only seen logical operators used as branch conditions in if, while, and for statements, and so they cannot see why these operators are useful. This section will show some uses of these operators.

## 3.9.1 Storing immediate values in registers

In MARS, the li instruction is translated into an "addui Rd, $zero, Immediate" instruction. This is perfectly valid, however when doing addition there always has to be propagation of a carry-bit, and so addition can take a relatively long time (O(logn)..O(n)). However the OR operation is a bit-wise operation and does not have any carry bits, and can be executed in O(1) time. In MARS the OR is not faster than addition, but in some architectures the OR is in fact faster than addition. If the OR is faster than addition, the li instruction can be implemented as "ori Rd, $zero, Immediate" with some advantage. Be aware that an ori is not the same as an addui. This difference is shown in problem 14 at the end of the chapter.

## 3.9.2 Converting a character from upper case to lower case

Chapter 1 pointed out that in ASCII the difference between upper case and lower case letters is the 0x20 bit. So an upper case letter can be converted to lower case by setting this bit to 1, and an upper case letter can be set to a lower case letter by turning this bit off. One of the exercises in Chapter 1 asked for an implementation of this program in a HLL. Many novice programmers see this problem and realize that convert uppercase letters to lowercase, they can add 0x20. The problem is that if the letter is already uppercase, the result is no longer a letter.

To correctly handle converting from uppercase to lowercase, the letters should be OR'ed with 0x20 (converting from lowercase to uppercase is left as an exercise at the end of the chapter). If this is done, letters which are already lowercase are not changed. This is illustrated in the following program.

Program 3-5: Letter case conversion in assembly

# File:       Program3-5.asm
# Author:     Charles Kann
# Purpose:    This program shows that adding 0x20 to a character can result in an error
#             when converting case, but or'ing 0x20 always works.
.text
.globl main
main:
# Show adding 0x20 only works if the character is upper case.
ori $v0,$zero, 4
la $a0, output1 syscall ori$t0, $zero, 0x41# Load the character "Z" addi$a0, $t0, 0x20 # Convert to "z" by adding ori$v0, $zero, 11 # Print the character syscall ori$v0, $zero, 4 la$a0, output2
syscall
ori $t0,$zero,0x61 # Load the character "z"
addi $a0,$t0, 0x20 # Attempt to convert to lower case
ori $v0,$zero, 11 # Print the character, does not work
syscall

# Show or'ing 0x20 works if the character is upper or lower case.
ori $v0,$zero, 4
la $a0, output1 syscall ori$t0, $zero, 0x41# Load the character "Z" ori$a0, $t0, 0x20 # Convert to "z" by adding ori$v0, $zero, 11 # Print the character syscall ori$v0, $zero, 4 la$a0, output1
syscall
ori $t0,$zero,0x61 # Load the character "z"
ori $a0,$t0, 0x20 # Attempt to convert to lower case
ori $v0,$zero, 11 # Print the character, does not work
syscall

ori $v0,$zero, 10  # Exit program
syscall
.data
output1: .asciiz "\nValid conversion: "
output2: .asciiz "\nInvalid conversion, nothing is printed: "


## 3.9.3 Reversible operations with XOR

Often it is nice to be able to invert the bits in a value in a way that they are easily translated back to the original value. Inverting the bits and restoring them is shown in the program below. One use of this is to swap two values without using a temporary storage space, is given at the end of the chapter.

# File:        Program3-6.asm
# Author:      Charles Kann
#Purpose:      To show the XOR operation is reversible
.text
.globl main
main:
ori $s0,$zero, 0x01234567 # the hex numbers

# Write out the XOR'ed value
la $a0, output1 li$v0, 4
syscall
xori $s0,$s0, 0xffffffff  # the results in $t1 will be fedcba98 move$a0, $s0 li$v0, 34
syscall

# Show the original value has been restored.
la $a0, output2 li$v0, 4
syscall
xori $s0,$s0, 0xffffffff  # the results in $t1 will be fedcba98 move$a0, $s0 li$v0, 34
syscall

ori $v0,$zero, 10         # Exit program
syscall
.data
output1: .asciiz "\nAfter first xor: "
output2: .asciiz "\nAfter second xor: "



3.9: Using Logical Operators is shared under a CC BY 4.0 license and was authored, remixed, and/or curated by Charles W. Kann III.