7.1: Program Control Flow
- Page ID
- 76125
\( \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}\)This section demonstrates the use of the pc register to control the flow of program logic. To start, a simple function called increment is created, and this function is called from the main function. In the main function a variable called numToInc is created, and the increment function is called using the Branch-and-Link (bl) operator. The variable numToInc is passed to the function in r0, where it is incremented by 1 and returned back in r0.
This program is then run in gdb, and the value in the pc and lr registers follow to show how the pc is used to control program flow in this program.
7.1.1 main and increment functions
The program that will be used to illustrate program control flow is Program 9. The rest of this section will run this program in gdb and demonstrate how the pc and ldr registers are used in program control flow. To follow along with this discussion, enter this program into a file named incrementMain.s, compile and link the program, and begin to run the program, stopping it at the first line in the main method.
.global main main: # Save return to os on stack SUB sp, sp, #4 STR lr, [sp, #0] # Prompt for and read input LDR r0, =promptForNumber BL printf LDR r0, =inputNumber LDR r1, =numToInc BL scanf # Increment numToInc by calling increment LDR r0, =numToInc LDR r0, [r0, #0] Bl increment # Printing the answer MOV r1, r0 LDR r0, =formatOutput BL printf # Return to the OS LDR lr, [sp, #0] ADD sp, sp, #4 MOV pc, lr .data promptForNumber: .asciz "Enter the number you want to increment: \ n" formatOutput: .asciz "\nThe input + 1 is %d\n" inputNumber: .asciz "%d" numToInc: .word 0 #end main .text #function increment increment: ADD r0, r0, #1 MOV pc, lr #end increment
9 Increment function
When the program reaches the breakpoint in the main, the screen should appear as follows:
Figure 62: Start of the program to call the increment function
In this figure, the column to the left of the source program is the address in memory of that instruction. As this figure shows, the value in the pc register is the same as this address, and this shows that the pc register contains the current instruction that is being executed. By walking through the program using the next command, the next instruction is always 4 bytes away from the current instruction, and the pc is increased by 4. This is how the program runs sequential instructions in a program, by increasing the value of the pc register by 4 for each instruction.
Now set a break point at line 17, and continue running the program. Enter a value or 5 when the program pauses for input at the scanf statement. The program will stop at address 0x1045c, the bl instruction that references the increment function. This is shown in the following screen shot.
Figure 63: The branch and link command for the increment function
The branch instruction is used to cause the program to jump to an address other than the next sequential statement. This branch statement contains the value 0x10478, which is the address of the start of the increment function.
For now, think of the bl instruction as a function call. When calling a function, it is expected that when the function completes, it will return to the instruction after call to the function. In this case, that is the “MOV r1, r0” statement at address 0x10460. To allow the function to return to this address, the lr register is loaded with this address.
The step command (not the next command) in gdb steps into the method. Using step, step to the first instruction in increment. Notice the value in the pc is 0x10478, and the value in lr is 0x10460, as expected.
Figure 64: First statement when entering the increment function
The second instruction in the increment method is a “MOV pc, lr”, which moves the value in the lr (the return point in main) into the pc, which causes the program to return to the main. The screen after running this instruction should look as follows:
Figure 65: Return from the increment function
This shows the return from the function. This example is how the control of flow in a program is combined for a function using a combination of the pc and lr registers.
The important thing to remember about this section is that the pc controls program flow and is possibly the most important register in a computer.