10.6: Call By Reference and Call By Reference Variable
- Page ID
- 83035
\( \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 basic programming classes cover the concept of Call By Value and Call By Reference. The concept is that a when calling a function, a parameter can be copied when the function is called (Call By Value) or the parameter can be a reference to the variable (Call By Reference). When Call By Value is used, the parameter cannot be changed, whereas when a Call By Reference is used, the values in the variables (which is always a multi-valued variable) can be changed. The following simple Java program to reversed an array illustrates this implementation of call by reference, where a multi-valued reference variable, an array, is passed to a function with two index offsets. The values in the array is then swapped.
.text .global main SwapByRefType: SUB sp, sp, #4 STR lr, [sp, #0] ADD r1, r0, r1, lsl #2 ADD r2, r0, r2, lsl #2 LDR r0, [r1, #0] LDR r3, [r2, #0] STR r0, [r2, #0] STR r3, [r1, #0] # pop stack and return LDR lr, [sp, #0] ADD sp, sp, #4 MOV pc, lr .data #END SwapByRefType main: # Save return to os on stack SUB sp, sp, #16 STR lr, [sp, #0] STR r4, [sp, #4] STR r5, [sp, #8] STR r6, [sp, #12] # Call PrintArray with the ar LDR r0, =output BL printf LDR r0, =ar LDR r1, =size LDR r1, [r1, #0] BL printArrayByIndex LDR r0, =newline BL printf # Reverse Array using SwapByRef #initialize loop LDR r4, =ar @ r4 is the base of the array LDR r7, =size LDR r7, [r7, #0] SUB r7, r7, #1 @ -1 for array index ASR r5, r7, #1 @ r5 is the loop limit, or or size by 2 MOV r6, #0 @ r6 is counter startMoveLoop: # Check end condition CMP r6, r5 BGE endMoveLoop MOV r0, r4 MOV r1, r6 SUB r2, r7, r6 BL SwapByRefType # next iteration ADD r6, r6, #1 b startMoveLoop endMoveLoop: # Call PrintArray with the ar LDR r0, =output BL printf LDR r0, =ar MOV r1, #5 BL printArrayByIndex LDR r0, =newline BL printf # Return to the OS LDR lr, [sp, #0] LDR r4, [sp, #4] LDR r5, [sp, #8] LDR r6, [sp, #12] ADD sp, sp, #16 MOV pc, lr .data output: .asciz "The array is : \n" newline: .asciz "\n" # the variable ar id an array of 5 elments size: .word 5 ar: .word 15 .word 1 .word 27 .word 9 .word 16 #END main
In this Java program the array and both indices are copied into parameters before the call to the method, but the array is a reference to other variables. This is not a true Call By Reference, but rather a call using a Reference Variable. In many hll, such as Java, there does not exist a true Call By Reference, as it is hard to ensure program correctness and safety with true Call By Reference. In these languages, all parameters are copied when a function is called and are thus Call By Value. The difference between these two implementation of parameter passing can best be illustrated in assembly, and are implemented in the following two sections.
10.6.1 Call by Reference Variable
This first example is the equivalent of the previous Java program. In this program the address of the start of the array is passed to the swap method, along with the two index offset values. The references to the two variables in the array to be swapped are calculated, and the values are swapped. Note that the references to the values to be swapped were calculated in this function.
10.6.2 Call by Reference
In this example, only two parameters are passed to the function. These two parameters are the actual references, or addresses, for the variables to be swapped. The swapping of these two variables are visible in the calling program since the actual references, and not copies of the variables, are passed to the function. This is not possible to accomplish in a language such as Java. This is a true implementation of Call By Reference, not a Call By Reference Variable.
.text .global main SwapByRef: SUB sp, sp, #4 STR lr, [sp, #0] LDR r2, [r0, #0] LDR r3, [r1, #0] STR r2, [r1, #0] STR r3, [r0, #0] LDR lr, [sp, #0] ADD sp, sp, #4 MOV pc, lr .data #END SwapByRef main: # Save return to os on stack SUB sp, sp, #16 STR lr, [sp, #0] STR r4, [sp, #4] STR r5, [sp, #8] STR r6, [sp, #12] # Call PrintArray with the ar LDR r0, =output BL printf LDR r0, =ar LDR r1, =size LDR r1, [r1, #0] BL printArrayByIndex LDR r0, =newline BL printf # Reverse Array using SwapByRef #initialize loop LDR r4, =ar @ r4 is the base of the array LDR r7, =size LDR r7, [r7, #0] SUB r7, r7, #1 @ -1 for array index ASR r5, r7, #1 @ r5 is the loop limit, or or size by 2 MOV r6, #0 @ r6 is counter startMoveLoop: # Check end condition CMP r6, r5 BGE endMoveLoop ADD r0, r4, r6, lsl #2 SUB r3, r7, r6 ADD r1, r4, r3, lsl #2 BL SwapByRef # next iteration ADD r6, r6, #1 b startMoveLoop endMoveLoop: # Call PrintArray with the ar LDR r0, =output BL printf LDR r0, =ar MOV r1, #5 BL printArrayByIndex LDR r0, =newline BL printf # Return to the OS LDR lr, [sp, #0] LDR r4, [sp, #4] LDR r5, [sp, #8] LDR r6, [sp, #12] ADD sp, sp, #16 MOV pc, lr .data output: .asciz "The array is : \n" newline: .asciz "\n" # the variable ar id an array of 5 elements size: .word 5 ar: .word 15 .word 1 .word 27 .word 9 .word 16 #END main