Section 9.8: Changeable parameters implemented by pointers (Frame 4)                     [prev][home][     ]

Here's the CSC-1 assembler code in 2-column format to save space

   0:   LOD   K               15:  PARM1:   NUM   0
   1:   STD   PARM1           16:  PARM2:   NUM   0
   2:   LOD   L               17:  K:       NUM   15
   3:   STD   PARM2           18:  L:       NUM   20
   4:   CAL   AUGMENT         19:  Z:       NUM   -4
   5:   LOD   PARM1           20:  W:       NUM   6
   6:   STD   K               21:  AUGMENT: LOD   PARM1
   7:   LOD   Z               22:           ADD   PARM2
   8:   STD   PARM1           23:           STD   PARM1
   9:   LOD   W               24:           RET
  10:   STD   PARM2
  11:   CAL   AUGMENT
  12:   LOD   PARM1
  13:   STD   Z
  14:   HLT

By the way, this code breaks one of the cardinal rules of assembler programming, which is that comments must exist to explain what is going on in the code.

The way parameters are handled in the assembler subroutine augment is called call by value/result or call by copy-back. It is not exactly equivalent to the C program shown that uses pointers. However, as long as you don't look at the values of the parameters and their referents until the subroutine returns, the two methods appear identical.

If changeable parameters are implemented by pointers, then any changes to the parameters are reflected back to the calling routine's variables immediately. The copy back strategy above is not needed, since the parameters are really just aliases for the calling routine's variables. Let's see what this would look like in assembler.

First the call would look different since we would get the address of the calling routine's variable and store it into the parameter. Using the example augment above,

     augment (&k, l);   /* after this k is changed to be k+l */

we would do the following:

     LDI   K
     STD   PARM1     ;  K is changeable, so get its address
     LOD   L
     STD   PARM2     ;  L is simply call by value, not changeable

Now in the augment subroutine itself, we would see the following:

void augment (int *parm1, int parm2) {
     int temp = *parm1 + parm2;
     *parm1 = temp;
}

The original code has been expanded and temporaries have been inserted to clarify the steps. To get the value of *parm1, we do the following:

     LOD   PARM1     ; has the address of the true parameter
     A2S
     LDS             ; A register now has current value of *parm1

     ADD   PARM2
     STD   TEMP

To stash the value back into *parm1, we need to use indirect store:

     LOD   PARM1     ; has the address of the true parameter
     A2S
     LOD   TEMP      ; what will get stored into *parm1
     STS             ; go ahead and store, using S's value as address

Putting all these lines together is how we would encode the original statement:

               ;  *parm1 += parm2;
     LOD   PARM1     ; has the address of the true parameter
     A2S
     LDS             ; A register now has current value of *parm1
     ADD   PARM2
     STD   TEMP
     LOD   PARM1     ; has the address of the true parameter
     A2S
     LOD   TEMP      ; what will get stored into *parm1
     STS             ; go ahead and store, using S's value as address

If you don't have an appreciation for the tremendous work that compilers and high level languages do for you, then you a hopeless dolt!