Skip to content
Rodion Gorkovenko edited this page Jan 24, 2015 · 5 revisions

All instructions we have learned previously are intended for "sequential" execution - i.e. in the same order they are written in your source.

However they could not be very useful if CPU have no ability to test some conditions and perform some choices depending on them.

###Unconditional jumps

Let us at first discuss simple jumps. They test no conditions and work as goto operators:

  • JUN - jumps unconditionally to specified code address

Since it is inconvenient to calculate code addresses manually, we will use labels to mark certain places in our sources and specify them instead of addresses. Note that labels themselves are not instructions (CPU knows nothing about your source). For example:

ldm 5
xch r0
jun skip_few
ldm 6
xch r1
skip_few:
ldm 7
xch r2

Run this to see that values 5 and 7 were stored to r0 and r2 but the middle fragment was skipped because of JUN instruction. Note that label is just an arbitrary identifier ending with colon.

In this example we can calculate that label skip_few equals to address $6 so we can write jun 6 instead.

###Conditional Jumps

CPU can test few conditions to decide whether to jump or not. Most useful of them for us are those on the state of Carry flag (set or clear) and of Accumulator (zero or not). All these are performed by JCN instruction which uses modifier of special kind before label:

  • JCN C0 - jump if Carry is not set (cy = 0)
  • JCN C1 - jump if Carry is set (cy = 1)
  • JCN AZ - jump if Accumulator equals to zero
  • JCN AN - jump if Accumulator is not zero

If the condition holds, this instruction jumps to supplied address. Otherwise it simply skips to next instruction without doing anything.

Consider an example of summation 4+3+2+1 in a loop:

ldm 4     ; load 4 to r0 - it will be counter
xch r0

one_more:

clc       ; add r0 to r1 which will hold the total
ld r1
add r0
xch r1

ld r0     ; decrement r0 via acc
dac
xch r0
jcn c1 one_more ; and jump if there was no borrow

Special form of Conditional Jump is represented by ISZ (increment and skip if zero) instruction which is also a special form of increment on register:

  • ISZ increment register and jump to target address if register does not become zero

This instruction may be helpful in creating loops running for given amount of iterations (like for-loop).

###Subroutine jumps

There are two instructions providing functionality of subroutines - i.e. pieces of code where you can jump and after doing something return back to instruction following the initial jump:

  • JMS - jump to subroutine - works as JUN but return address (i.e. of the next instruction) is pushed into stack of processor
  • BBL - "branch back and load" - pops the address from stack and jumps to it - so it is a return from subroutine; it additionally loads supplied value to accumulator (e.g. bbl 7) which may serve as an error code etc

Here is a simple example:

ldm 0
xch r0

jms add_three
jms add_three
jms add_three
jun finish

add_three:
ld r0
iac
iac
iac
xch r0
bbl 0

finish:
nop

Running this example you will see that r0 is changed to 9 because add_three subroutine is called thrice.


Next: Working with RAM - Memory-related instructions