7.5: Loops
- Page ID
- 27138
\( \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}\)There are two basic loop structures found in most introduction to programming books. These two loops structures are sentinel controlled loops and counter controlled loops. These loops are similar to while loops and for loops in most programming languages, so in this text the while loop will be used to implement sentinel control loops, and the for loop to implement counter control loops. How to translate each of these looping structures from pseudo code into assembly language will be covered in the next two sections.
7.5.1 Sentinel control loop
The definition of a sentinel is a guard, so the concept of a sentinel control loop is a loop with a guard statement that controls whether or not the loop is executed. The major use of sentinel control loops is to process input until some condition (a sentinel value) is met. For example a sentinel control loop could be used to process user input until the user enters a specific value, for example -1. The following pseudo code fragment uses a while statement to implement a sentinel control loop which prompts for an integer and prints that integer back until the user enters a -1.
int i = prompt("Enter an integer, or -1 to exit") while (i != -1) { print("You entered " + i); i = prompt("Enter an integer, or -1 to exit"); }
The following defines the steps involved in translating a sentinel control loop from pseudo code into assembly.
- Set the sentinel to be checked before entering the loop.
- Create a label for the start of the loop. This is so that at the end of the loop the program control can branch back to the start of the loop.
- Create a label for the end of the loop. This is so the loop can branch out when the sentinel returns false.
- Put the check code in place to check the sentinel. If the sentinel check is true, branch to the end of the loop.
- Set the sentinel to be checked as the last statement in the code block for the loop, and unconditionally branch back to the start of the loop. This completes the loop structure, and you should have code that appears similar to the following:
.text #set sentinel value (prompt the user for input). la $a0, prompt jal PromptInt move $s0, $v0 start_loop: sne $t1, $s0, -1 beqz $t1, end_loop # code block la $a0, prompt jal PromptInt move $s0, $v0 b start_loop end_loop: .data prompt: .asciiz "Enter an integer, -1 to stop: "
- The structure needed for the sentinel control loop is now in place. The logic to be executed in the code block can be included, and any other code that is needed to complete the program. The final result of this program follows.
Program 7-7: Sentinel control loop program .text #set sentinel value (prompt the user for input). la $a0, prompt jal PromptInt move $s0, $v0 start_loop: sne $t1, $s0, -1 beqz $t1, end_loop # code block la $a0, output move $a1, $s0 jal PrintInt la $a0, prompt jal PromptInt move $s0, $v0 b start_loop end_loop: jal Exit .data prompt: .asciiz "\nEnter an integer, -1 to stop: " output: .asciiz "\nYou entered: " .include "utils.asm"
7.5.2 Counter control loop
A counter controlled loop is a loop which is intended to be executed some number of times. Normally this is associated with a for loop in most HLL. The general format is to specify a starting value for a counter, the ending condition (normally when the counter reaches a predetermined value) , and the increment operation on the counter. An example is the following pseudo code for loop which sums the values from 0 to n-1.
n = prompt("enter the value to calculate the sum up to: ") total = 0; # Initial the total variable for sum for (i = 0; i < n; i++) { total = total + i } print("Total = " + total);
The for
statement itself has 3 parts. The first is the initialization that occurs before the loop is executed (here it is "i=0
"). The second is the condition for continuing to enter the loop (here it is "i < size
"). The final condition specifies how to increment the counter (here it is "i++
", or add 1 to i). These 3 parts are included in the translation of the structure.
The following defines the steps involved in translating a sentinel control loop from pseudo code into assembly.
- Implement the initialization step to initialize the counter and the ending condition variables.
- Create labels for the start and end of the loop.
- Implement the check to enter the loop block, or stop the loop when the condition is met.
- Implement the counter increment, and branch back to the start of the loop. When you have completed these steps, the basic structure of the counter control loop has been implemented, and your code should look similar to the following:
.text li $s0, 0 lw $s1, n start_loop: sle $t1, $s0, $s1 beqz $t1, end_loop # code block addi $s0, $s0, 1 b start_loop end_loop: .data n: .word 5
- Implement the code block for the for statement. Implement any other code necessary to complete the program. The final assembly code for this program should look similar to the following.
Program 7-8: Counter control loop program .text la $a0, prompt jal PromptInt move $s1, $v0 li $s0, 0 li $s2, 0 # Initialize the total start_loop: sle $t1, $s0, $s1 beqz $t1, end_loop # code block add $s2, $s2, $s0 addi $s0, $s0, 1 b start_loop end_loop: la $a0, output move $a1, $s2 jal PrintInt jal Exit .data prompt: .asciiz "enter the value to calculate the sum up to: " output: .asciiz "The final result is: " .include "utils.asm"