12.1 trap (2693)

The way that this procedure is invoked was explored in Chapter Ten. The assembler “trap” routine carries out certain fundamental housekeeping tasks to set up the kernel stack, so that when this procedure is called, everything appears to be kosher.

The “trap” procedure can operate as though it had been called by another “C” procedure in the normal way with seven parameters

dev, sp, rl, nps, r0, pc, ps.

(There is a special consideration which should be mentioned here in passing. Normally all parameters passed to “C” procedures are passed by value. If the procedure subsequently changes the values of the parameters, this will not affect the calling procedure directly.

However if “trap” or the interrupt handlers change the values of their parameters, the new values will be picked up and reflected back when the “previous mode” registers are restored.)

The value of “dev” was obtained by capturing the value of the processor status word immediately after the trap and masking out all but the lower five bits. Immediately before this, the processor status word had been set using the prototype contained in the appropriate vector location.

Thus if the second word of the vector location was “br7+n;” (e.g. line 0516) then the value of “dev” will be n.

2698:

“savfp” saves the floating point registers (for the PDP11/40, this is a no-op!);

2700:

If the previous mode is “user mode’, the value of “dev” is modified by the addition of the octal value 020 (2662);

2701:

The stack address where r0 is stored is noted in “u.u_ar0” for future reference. (Subsequently the various register values can be referenced as “u.u_ar0[Rn]”.);

2702:

There is now a multi-way “switch” depending on the value of “dev”.

At this point we can observe that UNIX divides traps into three classes, depending on the prior processor mode and the source of the trap:

(a)

kernel mode;

(b)

user mode, not due to a “trap” instruction;

(c)

user mode, due to a “trap” instruction.