Warning: preg_match(): Compilation failed: group name must start with a non-digit at offset 8 in /home/content/30/6867330/html/intellivision/wiki/includes/MagicWord.php on line 722

Warning: preg_match(): Compilation failed: group name must start with a non-digit at offset 8 in /home/content/30/6867330/html/intellivision/wiki/includes/MagicWord.php on line 722

Warning: preg_match_all(): Compilation failed: group name must start with a non-digit at offset 4 in /home/content/30/6867330/html/intellivision/wiki/includes/MagicWord.php on line 700

Warning: Invalid argument supplied for foreach() in /home/content/30/6867330/html/intellivision/wiki/includes/MagicWord.php on line 701

Warning: preg_replace(): Compilation failed: group name must start with a non-digit at offset 4 in /home/content/30/6867330/html/intellivision/wiki/includes/MagicWord.php on line 705

Warning: preg_match_all(): Compilation failed: group name must start with a non-digit at offset 4 in /home/content/30/6867330/html/intellivision/wiki/includes/MagicWord.php on line 700

Warning: Invalid argument supplied for foreach() in /home/content/30/6867330/html/intellivision/wiki/includes/MagicWord.php on line 701

Warning: preg_replace(): Compilation failed: group name must start with a non-digit at offset 4 in /home/content/30/6867330/html/intellivision/wiki/includes/MagicWord.php on line 705

Warning: preg_match_all(): Compilation failed: group name must start with a non-digit at offset 4 in /home/content/30/6867330/html/intellivision/wiki/includes/MagicWord.php on line 700

Warning: Invalid argument supplied for foreach() in /home/content/30/6867330/html/intellivision/wiki/includes/MagicWord.php on line 701

Warning: preg_replace(): Compilation failed: group name must start with a non-digit at offset 4 in /home/content/30/6867330/html/intellivision/wiki/includes/MagicWord.php on line 705

Warning: preg_match_all(): Compilation failed: group name must start with a non-digit at offset 4 in /home/content/30/6867330/html/intellivision/wiki/includes/MagicWord.php on line 700

Warning: Invalid argument supplied for foreach() in /home/content/30/6867330/html/intellivision/wiki/includes/MagicWord.php on line 701

Warning: preg_replace(): Compilation failed: group name must start with a non-digit at offset 4 in /home/content/30/6867330/html/intellivision/wiki/includes/MagicWord.php on line 705

Warning: preg_match(): Compilation failed: group name must start with a non-digit at offset 8 in /home/content/30/6867330/html/intellivision/wiki/includes/MagicWord.php on line 722

Warning: preg_match(): Compilation failed: group name must start with a non-digit at offset 8 in /home/content/30/6867330/html/intellivision/wiki/includes/MagicWord.php on line 722

Warning: preg_match(): Compilation failed: group name must start with a non-digit at offset 8 in /home/content/30/6867330/html/intellivision/wiki/includes/MagicWord.php on line 722

Warning: preg_match(): Compilation failed: group name must start with a non-digit at offset 8 in /home/content/30/6867330/html/intellivision/wiki/includes/MagicWord.php on line 722

Warning: preg_match(): Compilation failed: group name must start with a non-digit at offset 8 in /home/content/30/6867330/html/intellivision/wiki/includes/MagicWord.php on line 722
Introducing the Instruction Set Part 3 - Intellivision Wiki

Introducing the Instruction Set Part 3


Warning: preg_match(): Compilation failed: group name must start with a non-digit at offset 8 in /home/content/30/6867330/html/intellivision/wiki/includes/MagicWord.php on line 722
From Intellivision Wiki

Jump to: navigation, search
(Indirect Branches and Jump Tables)
(Call Chaining)
Line 519: Line 519:
As you can see, this technique provides a great deal of flexibility in how things are called.
As you can see, this technique provides a great deal of flexibility in how things are called.
-
== Chaining Function Return ==
+
== Call Chaining:  Having One Function Return for Another ==
 +
Sometimes, the last thing you do at the end of one function is call another.  When that function returns, the only work left to do is to return again.  While that works, it's often possible to "chain" the return—that is, let the function you're calling return for you.  Note that this is purely an optimization.  If it is at all unclear to you, I recommend you steer clear of it unless you're in a crunch.
 +
<BR/><BR/>
 +
For example, suppose we write a function that spins for a moment and then clears the screen.  (Note:  There are many ways to do this with different advantages and disadvantages.  This way has the advantage of being easy to write.)
 +
<BR/><BR/>
 +
Here's an example of the delayed clear, showing a normal call/return sequence:
 +
 +
; Delay for a moment and then clear the screen
 +
DLYCLR  PROC
 +
        [[PSHR]]    R5          ; Save the return address
 +
 +
        [[MVII]]    #$FFFF, R0
 +
        ; Loop a bunch of times doing nothing
 +
@@spin: [[NOP]]
 +
        [[NOP]]
 +
        [[DECR]]    R0
 +
        [[BNEQ]]    @@spin
 +
 +
        ; Now clear the screen
 +
        [[CALL]]    CLRSCR
 +
 +
        [[PULR]]    PC          ; Return to our caller
 +
        ENDP
 +
 +
Here, we save our return address, then we call out to <CODE>CLRSCR</CODE>.  At the end, <CODE>CLRSCR</CODE> returns to us, and we return to our caller.  This can be made more efficient by having <CODE>CLRSCR</CODE> return directly to our caller for us.  This saves stack space (which is often at a premium) and can save cycles.  Consider the following version of the above example:
 +
 +
; Delay for a moment and then clear the screen
 +
DLYCLR  PROC
 +
        [[MVII]]    #$FFFF, R0
 +
        ; Loop a bunch of times doing nothing
 +
@@spin: [[NOP]]
 +
        [[NOP]]
 +
        [[DECR]]    R0
 +
        [[BNEQ]]    @@spin
 +
 +
        ; Now clear the screen and return
 +
        [[B]]      CLRSCR
 +
        ENDP
 +
 +
Notice how this version of the code doesn't save the return address, and in fact doesn't do anything with it.  Instead of using <CODE>[[CALL]]</CODE> to invoke <CODE>CLRSCR</CODE>, it merely branches to it.  Since the return address for <CODE>DLYCLR</CODE> is already in R5, when <CODE>CLRSCR</CODE> completes and branches to it, it'll return to <CODE>DLYCLR</CODE>'s caller.  This is what "call chaining" is all about:  In this case, <CODE>CLRSCR</CODE> returns on behalf of <CODE>DLYCLR</CODE>.  Rather than having <CODE>DLYCLR</CODE> call <CODE>CLRSCR</CODE>, it instead branches&mdash;aka. chains&mdash;to it.
 +
<BR/><BR/>
 +
It's not always possible to chain calls like this.  In particular, if you pass arguments after your <CODE>[[CALL]]</CODE> instruction, as described above, you cannot chain to that call.
 +
<BR/><BR/>
 +
As a stylistic thing, I suggest avoiding call-chaining unless you need the stack space, code space or cycles that it saves.  Write your code initially without it, and optimize later if you need it.
= Indirect Branches and Jump Tables =
= Indirect Branches and Jump Tables =

Revision as of 23:02, 6 November 2007

Personal tools
Namespaces
Variants
Actions
Navigation
Toolbox