Parameter Passing: Difference between revisions

 
(3 intermediate revisions by one other user not shown)
Line 23:
Certain commands such as <code>INC</code>,<code>DEC</code>,<code>ASL</code>,<code>LSR</code>,<code>ROL</code>, and <code>ROR</code> inherently alter the memory address that is used as an argument. Thus their use on a memory address is pass-by-reference.
 
<syntaxhighlight lang="6502asm">
<lang 6502asm>ROL $81 ;rotate left the bits of the value stored at memory address $0081. The old value of $0081 is discarded.
INCROL $2081 ;addrotate 1left tothe bits of the value stored at memory address $200081. The old value of $0081 is discarded.</lang>
INC $20 ;add 1 to the value at memory address $20.
</syntaxhighlight>
 
However, opcodes that use a register as their primary operand are strictly pass-by-value.
 
<syntaxhighlight lang="6502asm">
<lang 6502asm>ADC $81 ;add the value stored at memory address $81 to the accumulator. The value at memory address $81 is unchanged.
;If the carry was set prior to this operation, also add an additional 1 to the accumulator.
 
Line 39 ⟶ 42:
 
LDA $40 ;load the value stored at memory address $40 into the accumulator
ROR A ;rotate right the accumulator. This is only a copy. The actual value stored at $40 is unchanged.</lang>
</syntaxhighlight>
 
The main takeaway from this is that by default, the use of <code>LDA/LDX/LDY</code> commands to load from memory is pass-by-value. In order to actually update the memory location, you must store the value back into the source memory address.
Line 47 ⟶ 51:
Generally, parameters are either passed using the stack or with temporary zero-page memory addresses. While these are both forms of memory that are getting overwritten, the actual sources of the data remain the same.
=====Example of in (immutable)=====
<syntaxhighlight lang ="6502asm"> lda sourceData
lda sourceData
jsr MultiplyBy4
 
Line 54 ⟶ 59:
lsr A
lsr A
rts</lang>
</syntaxhighlight>
 
=====Example of out (result)=====
This routine reads the joystick output on Commodore 64 and stores it in the output variable <code>joystick1</code>.
<langsyntaxhighlight lang="6502asm">ReadJoystick:
ReadJoystick:
lda $DC00
ora #%11100000
sta joystick1
rts</lang>
</syntaxhighlight>
 
=====Example of in/out (mutable)=====
This one's tricky because of the way pointers work on the 6502. Unlike the other architectures of its day there are no "address registers" per se, but we can make our own using the zero page.
 
<langsyntaxhighlight lang="6502asm">
LDA #$03 ;load the low byte of the parameter's address
STA $20 ;store it in the low byte of our pointer variable.
Line 83 ⟶ 93:
adc #$20 ; 0x20 = decimal 32
sta ($20),y ; overwrite the old value stored in $0003 with the new one.
rts</lang>
</syntaxhighlight>
 
===Example [[68000 Assembly]]===
Line 89 ⟶ 100:
Parameters are typically passed via the stack or through registers. For human-written assembly, the programmer can pass an argument by reference by passing a pointer to the argument rather than the argument itself. Of course, the function will need to dereference that pointer; however whether the function writes back the new value to that memory address is also decided by the programmer. This means that just because a parameter is passed by reference does not mean that it gets altered by the function that received it. This (contrived) example shows this concept in action.
 
<langsyntaxhighlight lang="68000devpac">start:
start:
MOVE.L #$00FF0000,D0 ;load D0 with the pointer 0x00FF0000 (I decided this was a pointer just for example's sake.)
MOVE.L D0,-(SP) ;push that value onto the stack.
Line 102 ⟶ 114:
MOVE.L (A0),D1 ;dereference the pointer (we're treating it as a pointer to an int)
ADD.L D1,D0 ;add the values.
RTS ;and return</lang>
</syntaxhighlight>
 
 
===Example [[Ada]]===
Line 138 ⟶ 150:
 
===Example [[Fortran]]===
Early versions of the language used only by reference parameter passing for the arguments, but the formal parameters were copied locally and then copied back to the actual parameters at the end of the call. This is also known as "call by value result" or "call by copy-restore".
 
Starting from Fortran 90 (and later), functions and subroutines can specify an ''intent'' for the argument; intent can be: '''in''' (unmodificableunmodifiable argument), '''out''' (argument used to return a value; the starting value must be intended not significativesignificant, undefined), '''inout''' (argument both is intended for input and can be modified, i.e. return the value modified by the function/subroutine).
 
Trying to modify an argument with ''intent in'' triggers an error at compile time.
44

edits