3.9: Using Logical Operators
- Page ID
- 28490
\( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)
\( \newcommand{\vecd}[1]{\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]{\| #1 \|}\)
\( \newcommand{\inner}[2]{\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]{\| #1 \|}\)
\( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\)
\( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\AA}{\unicode[.8,0]{x212B}}\)
\( \newcommand{\vectorA}[1]{\vec{#1}} % arrow\)
\( \newcommand{\vectorAt}[1]{\vec{\text{#1}}} % arrow\)
\( \newcommand{\vectorB}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)
\( \newcommand{\vectorC}[1]{\textbf{#1}} \)
\( \newcommand{\vectorD}[1]{\overrightarrow{#1}} \)
\( \newcommand{\vectorDt}[1]{\overrightarrow{\text{#1}}} \)
\( \newcommand{\vectE}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash{\mathbf {#1}}}} \)
\( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)
\( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)
\(\newcommand{\avec}{\mathbf a}\) \(\newcommand{\bvec}{\mathbf b}\) \(\newcommand{\cvec}{\mathbf c}\) \(\newcommand{\dvec}{\mathbf d}\) \(\newcommand{\dtil}{\widetilde{\mathbf d}}\) \(\newcommand{\evec}{\mathbf e}\) \(\newcommand{\fvec}{\mathbf f}\) \(\newcommand{\nvec}{\mathbf n}\) \(\newcommand{\pvec}{\mathbf p}\) \(\newcommand{\qvec}{\mathbf q}\) \(\newcommand{\svec}{\mathbf s}\) \(\newcommand{\tvec}{\mathbf t}\) \(\newcommand{\uvec}{\mathbf u}\) \(\newcommand{\vvec}{\mathbf v}\) \(\newcommand{\wvec}{\mathbf w}\) \(\newcommand{\xvec}{\mathbf x}\) \(\newcommand{\yvec}{\mathbf y}\) \(\newcommand{\zvec}{\mathbf z}\) \(\newcommand{\rvec}{\mathbf r}\) \(\newcommand{\mvec}{\mathbf m}\) \(\newcommand{\zerovec}{\mathbf 0}\) \(\newcommand{\onevec}{\mathbf 1}\) \(\newcommand{\real}{\mathbb R}\) \(\newcommand{\twovec}[2]{\left[\begin{array}{r}#1 \\ #2 \end{array}\right]}\) \(\newcommand{\ctwovec}[2]{\left[\begin{array}{c}#1 \\ #2 \end{array}\right]}\) \(\newcommand{\threevec}[3]{\left[\begin{array}{r}#1 \\ #2 \\ #3 \end{array}\right]}\) \(\newcommand{\cthreevec}[3]{\left[\begin{array}{c}#1 \\ #2 \\ #3 \end{array}\right]}\) \(\newcommand{\fourvec}[4]{\left[\begin{array}{r}#1 \\ #2 \\ #3 \\ #4 \end{array}\right]}\) \(\newcommand{\cfourvec}[4]{\left[\begin{array}{c}#1 \\ #2 \\ #3 \\ #4 \end{array}\right]}\) \(\newcommand{\fivevec}[5]{\left[\begin{array}{r}#1 \\ #2 \\ #3 \\ #4 \\ #5 \\ \end{array}\right]}\) \(\newcommand{\cfivevec}[5]{\left[\begin{array}{c}#1 \\ #2 \\ #3 \\ #4 \\ #5 \\ \end{array}\right]}\) \(\newcommand{\mattwo}[4]{\left[\begin{array}{rr}#1 \amp #2 \\ #3 \amp #4 \\ \end{array}\right]}\) \(\newcommand{\laspan}[1]{\text{Span}\{#1\}}\) \(\newcommand{\bcal}{\cal B}\) \(\newcommand{\ccal}{\cal C}\) \(\newcommand{\scal}{\cal S}\) \(\newcommand{\wcal}{\cal W}\) \(\newcommand{\ecal}{\cal E}\) \(\newcommand{\coords}[2]{\left\{#1\right\}_{#2}}\) \(\newcommand{\gray}[1]{\color{gray}{#1}}\) \(\newcommand{\lgray}[1]{\color{lightgray}{#1}}\) \(\newcommand{\rank}{\operatorname{rank}}\) \(\newcommand{\row}{\text{Row}}\) \(\newcommand{\col}{\text{Col}}\) \(\renewcommand{\row}{\text{Row}}\) \(\newcommand{\nul}{\text{Nul}}\) \(\newcommand{\var}{\text{Var}}\) \(\newcommand{\corr}{\text{corr}}\) \(\newcommand{\len}[1]{\left|#1\right|}\) \(\newcommand{\bbar}{\overline{\bvec}}\) \(\newcommand{\bhat}{\widehat{\bvec}}\) \(\newcommand{\bperp}{\bvec^\perp}\) \(\newcommand{\xhat}{\widehat{\xvec}}\) \(\newcommand{\vhat}{\widehat{\vvec}}\) \(\newcommand{\uhat}{\widehat{\uvec}}\) \(\newcommand{\what}{\widehat{\wvec}}\) \(\newcommand{\Sighat}{\widehat{\Sigma}}\) \(\newcommand{\lt}{<}\) \(\newcommand{\gt}{>}\) \(\newcommand{\amp}{&}\) \(\definecolor{fillinmathshade}{gray}{0.9}\)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: "