68000 software - high-level language interface

When input/output devices are addressed, virtual addresses cannot be used. Only physical addresses can be used and a user is unable to directly access physical addresses for security reasons.
In such cases, a user must request the operating system to perform the data transfer, as only the operating system (running under Supervisor status) has the necessary privilege to bypass the address translation of a PMMU.
This is achieved by the use of a set of predefined TRAP calls and device drivers.

One example is given below which is a call to a Unix function to create a file called name with a mode which specifies whether the file is for read-only, read-write, write-only or to append data, for example. TRAP #0 is the trap for file-system requests, the parameter given in register D0 specifies the file operation (8=create, 6=close etc.).

	creat(char *name, int mode); /* this is the C call to the O.S. */
;the compiler converts this to machine code as follows:
	movl	#8, d0
	movl	#name, a0
	movl	mode d1
	trap 	#0
On return from the trap, a file descriptor is returned in D0.

Passing parameters

Parameters are normally passed from one routine to another, using the stack.
For example:
	abcd(x, y, z);		 
is a function call which places the parameters on the stack in reverse order, followed by the return address for the ensuing JSR instruction.

z
y
x
RA
 
The Stack Pointer (SP) is left pointing to the return address (RA) entry.

The called routine (abcd) accesses parameters relative to SP, i.e.

1st parameter is atSP+4
2nd parameter is atSP+8
3rd parameter is atSP+12

In some RISC processors, the convention is to use registers rather than memory to pass parameters. Since the number of parameters is unknown and may sometimes be quite large, up to the first 4 parameters may be passed in registers and the rest on the stack, as above.

LINK and UNLINK

Subroutines can often call other subroutines. In addition, automatic variables are created on the stack. This can give rise to a complex set of data saved on the stack. The stack needs to be restored to its original state before the RTS is executed, as this needs to find a valid return address.

LINK and UNLINK are provided to create a stack frame and to enable the stack to be restored quickly and easily.

The LINK instruction (e.g. LINK An, #-offset) causes the following actions:

An--> -(Sp)push An onto the stack
SP-->Ancopy Sp into An
SP+disp-->Spdecrement Sp by offset
So LINK a6,#-16 has the following effect on the stack:

old TOS
old a6
 
 
 
 
new TOS
where Sp is left pointing to the new TOS, a6 (the link register) points to the old a6 location and 4 words are reserved on the stack for the subroutine's use. These locations will never be overwritten by the stack during the execution of this subroutine.

Software example

An example is given of how a high-level language (such as C) is interfaced to a microprocessor operating system (such as Unix).
Particular attention is given to how variables are stored and how a paged memory management unit affects the software.
main()
{
int x,y;
char z;
.
 abcd(x, y, z);
.
}
abcd(int u, int v, char w)
{
int a;
.
.
.
}

If the subroutine abcd() were written instead in 68000 assembly language, to run on a 68000-based paged memory management systems, the following instructions are necessary.
The stack locations used in this example were given in the lecture.
Note 1
Note 2
Note 3
Note 4


Note 5


Note 6


Note 7


Note 8
Note 9
Note 10
Note 11
regs
rmask
_abcd:
=16
=0xc3
link a6,#-regs
tstb sp@(-136)
.
.
moveml #rmask, a6@(-regs)
.
movl a6@(8), a2
movl a6@(12), a3
movl a6@(16), d0
.
subql #4, sp
.
.
movl d1, d0
moveml a6@(-regs), #rmask
unlk a6
rts
Note 1regs is a constant declaration
Note 2rmask is a 16-bit value which determines the registers which will be used in the later moveml instructions.
A7A6A5A4A3A2A1A0 D7D6D5D4D3D2D1D0
00001100 00000011
0xC3 = A3, A2, D1, D0
Note 3The LINK instruction is explained above
Note 4This instruction probes the stack just before the moveml instruction. Should a page fault occur during the move-multiple-register instruction, which is indivisible, then this cannot be corrected. This is because the BERR trap which will be entered as a result of the page fault also uses the stack. So probing the stack 136 bytes further down (in this example) should provoke a page fault if the stack is close to a page boundary, and will ensure that sufficient RAM is available to allow the stack to grow downwards.
Note 5Here the registers a2, a1, d1, d0 are saved on the stack (at ascending addresses) in the memory locations reserved in the LINK instruction above. These registers are used in the routine, so are saved before use. They will be restored later.
Note 6The parameters passed on the stack are copied into registers for use in this subroutine.
Note 7The stack pointer is decremented to make space for the automatic variable w.
Note 8The result is held in d0 (as in the return() statement.
Note 9This restores the registers saved in Note 5 above.
Note 10UNLK copies a6 into Sp and then a6 is popped off the stack restoring the old value. Sp is now pointing to the return address (RA).
Note 11Return to the calling program using RA.

Back