You are on page 1of 0

Chap. 4 Subroutine & Interrupt p.

1 / 5

Chapter 4 : Subroutine and Interrupt

A good software program is written in such a way that it consists of a set of interactive modules in-
stead of one big monstrous program executed from beginning to end. This modular programming
can be seen as the programming of individual tasks which are linked together. Each task has a well
defined specification, performing a logical coherent job. The challenge of course is how to divide
one big job into smaller meaningfull units.

Modular programming offers a lot of benefits :
- the testability and maintenance is easier for each seperate module
- the modules could also be used in other projects
- the whole program can be easily upgraded by just replacing some of the smaller modules
- "... divide et impera .... " (J ulius Ceasar, 57 a.C.)

STACK

Every computer has a special memory unit. This memory is not used for the storage of program or
data but to save a number of values of the program counter. For reasons which will be obvious soon
this saving is done on a last-in first-out principle. In other words, the most recent values which are
stored will be removed (re-used) the first. The first (oldest) value will be restored latest. This action
could perfectly be done by a LIFO shiftregister. The LIFO used in the computer context is called a
stack. The stack refers to a stack of paper on which new papers are added but removed in reverse
sequence. The top of the stack (=TOS) is the only important item for the user: all other items in the
stack are not immediate accessible. The user will put new info on the stack (=push) or read info
from the stack (=pop). All these actions occor on the top of the stack, the other values are shifted
up or down.
Of course the number of pop operations should be equal to the number of push operations. If not a
underflow or overflow of the stack will occur.
Remark that the shifting action of a stack is quiet deceiving. The information is not shifted because
that would require complex hardware. Instead, a normal circular buffer with SRAM is used. The
pup and push actions will result in a manipulation of the read/write pointer. The data itself is not
moved around.

Subroutine

The subroutine is a collection of instructions which perform a well defined task. The reason to put
these instructions into a separate module (=subroutine) are not always evident. The execution of
the subroutine is done completely under control of the running program. The program itself will
call the subroutine module.




Chap. 4 Subroutine & Interrupt p. 2 / 5


What happens ?
The running program will force the program counter to jump to the starting address of the subrou-
tine. After execution of this routine the program flow should jump back to the location where the
program was left before the call of the subroutine. Principally the call of a subroutine can be unli-
mited. The program could call the subroutine over and over again.
This is one of the main reasons of using subroutines : it is an economical use of program memory.
Instead of writing the code every time in the main program it is written only once in the subroutine.

The call of the subroutine is as follows :

CALL subroutine_name

action : 1. push the present PC on the stack
2. push the address of the subroutine in the program counter PC

The label (=name of the subroutine) belonging to the first instruction of the subroutine has the val-
ue of the start-address of the subroutine.

Once the subroutine is executed it should return to the normal program flow

RETURN

action: restore the original value of the PC from stack (=TOS) to the program counter.


Example :

main instructie_1
instructie_2
CALL SUM
instructie_3
instructie_4
....
instruktie_k
CALL SUM
instruktie_p
instructie_q
...
...
; subroutine SUM
SUM sub_instructie_1
sub_instructie_2
sub_instructie_3
....
sub_instructie_n
RETURN


Chap. 4 Subroutine & Interrupt p. 3 / 5

Passing of parameters.


The concept of a subroutine is well known in the higher level programming languages (C, Pascal,
...). These languages have very elaborated possibilities of how the main program can pass parame-
ters the the subroutine and how the subroutine can pass results back to the main program.
In principle the hardware shouldn't take care of this passing. The software program can be con-
ceived such that a formal agreement between caller and callee (main and subroutine) is used to put
parameters on certain locations in memory.
The minimal task for the hardware is the saving of the program counter on the stack and the restor-
ing at completion of the subroutine.
The hardware itself has some restricted ways of passing information between the main program and
the subroutine. For instance, the register w and the status register contain 'main' information which
is accessible for the subroutine. Similar, on return these registers contain 'subroutine' information
accessible for the main program.

General speaking, the context of the main program is accessible for the subroutine. The context of
the program are those registers belonging to the CPU and containing the status of the CPU. This
context is accessible for the subroutine. More, the programmer knows exactly when and how the
subroutine will act on this information and, eventually, can modify it. The same is true for the com-
pletion of the subroutine. The main program will continue with the context of the subroutine.
If required, some extra registers could be used to communicate between the main and the subrou-
tine. The software has to take care of that.

A subroutine can call another subroutine. This will cause a new push on the stack before the pop of
the previous value of the program counter. The possibility of subroutines calling other subroutines
is called subroutine nesting. The depth of the nesting is restricted by the size of the stack. Funny
things can happen if the subroutine can call itself. This phenomenon is called re-entrant.
It is obvious that the passing of parameters has to be carefully organized.

The Better microprocessor has a stack which is not only used for the strictly necessary task of sav-
ing the program counter but also for saving the whole context. And even much more. The hardware
saving (-->automatically) is a nice feature but it requires an overhead in time. And maybe this
hardware saving could be an overkill for the job or maybe it just could be not enough. (...misery...)

If the computer has no elaborated stack mechanism or far any reason it is too small, the job could
always be executed by a software stack.

Chap. 4 Subroutine & Interrupt p. 4 / 5

INTERRUPT


Certain (mostly hardware) events are such that they force the computer to quit the normal program
flow to react fast on these events. It could be perfectly acceptable that the normal program flow for
the control of the air-conditioning is interrupted by a fire alarm.
Such an event that requires a fast response by the computer will be called an interrupt.

A lot can be told about interrupts and related stuff and this will be done in a later chapter. This sec-
tion will deal with the recognition and execution of an interrupt.

The collection of instructions which have to be executed to serve the interrupt can be considered as
a module (similar to the subroutine). This module is called the interrupt routine.

main program interrupt routine

instr.(n-1) int_instr.1
instr.(n) int_instr.2
instr.(n+1) int._....
instr.(n+2) intr_....
... intr_...
... RETFIE



The interrupt signal will cause the hardware to change the program flow. The current value of the
program counter will be pushed on the stack. Then the program counter will be loaded by a hard-
ware defined value. This value is the address of the first instruction of the interrupt routine. This
fixed address of the location of the interrupt routine is called the interrupt vector.
Normally this address is not as fixed as it looks to be. The virtual basic computer has its interrupt
vector at program memory location 0x04.

The occurance of the interrupt event is completely asynchronous to the current instruction N. Nor-
mally this instruction N will be completely executed before jumping to the interrupt routine.
After completion of the interrupt routine the normal program flow should continue. The instruction
RETFIE (Return from Interrupt) will pop the previous value of the program counter (N+1) from
stack and restore it into the program counter.

There seems to be only small differences between the subroutine and the interrupt routine :

subroutine : is called by the program itself. Predictable.
interrupt routine : is called by an external event. Unpredictable.

But there is a difference: the program doesn't "know" when the interrupt will appear.To keep things
simple the hardware will (normally) not allow that this interrupt will be interrupted once again dur-
ing the interrupt routine. The Global Interrupt Enable Flag (=GIE) will take care of that. The jump
to the interrupt routine will force GIE ='0' to prevent any further interrupt. However, the interrupt
routine is able to re-enable GIE ( GIE ='1') to allow interrupt during its execution.
Anyhow, on completion of the interrupt routine the hardware will automatically set the GIE flag
(GIE='1'). This is done by the execution of the RETFIE instruction.

Chap. 4 Subroutine & Interrupt p. 5 / 5


subroutine : RETURN TOS -----> PC

interrupt : RETFIE 1. TOS --->PC
2. GIE ='1'

The occurence of an interrupt could be "dangerous" for the context of the computer. Suppose that
the instruction (n) is performing an additon and that the carry should be checked by instruction
(n+1). It is possible that an external event will cause an interrupt which will force the computer to
jump to the interrupt routine after the execution of instruction (n), but before the execution of in-
struction (n+1). The interrupt routine will do all kind of instructions and most probably will affect
the carry. On completion of the interrupt the main program continues with the execution of instruc-
tion (n+1). Big problem : the carry is not anymore what it should be after the completion of (n).
It is imperative to save the context of the interrupted program. This job should be done by the inter-
rupt routine and before the proper interrupt code. After the execution of the proper interrupt code
the context should be restored before the RETFIE is executed.
What data that should be considered to save and restore is dependant on the actions of the interrupt
routine. Too many data couldn't hurt but will result in a waste of time. Too less will be catastrophic.

POLLING

An alternative for the interrupt is the polling of events. The events will be checked by the program
on a regular time base. The jump to the required processing module will be executed when the
event is observed.

The polling has it reason of existance :

interrupt : fast response, no waste of time for a continueous checking
unpredictable occurence requires context saving

polling : slow response, waste of time in checking non-events
predictable, synchronous with the software : no context saving required.

You might also like