User mode programs use “trap” instructions as part of the “system call” mechanism to call upon the operating system for assistance.
Since there are many possible “versions” of the “trap” instruction, the type of assistance requested can be and is encoded as part of the “trap” instruction.
Parameters which are part of a system call may be passed from the user program in different ways:
via the special register r0;
as a set of words embedded in the program string following the “trap” instruction;
as a set of words in the program’s data area. (This is the “indirect” call.)
Indirect calls have a higher overhead than direct system calls. Indirect calls are needed when the parameters are data dependent and cannot be determined at compile time.
Indirect calls may sometimes be avoided if there is only one data dependent parameter, which is passed via r0. In choosing which parameters should be passed via r0, the system designers have presumably been guided by their own experience, since the pattern doesn’t satisfy the law of least astonishment.
The “C” compiler does not give special recognition to system calls, but treats them in the same way as other procedures. When the loader comes to resolve undetermined references, it satisfies these with library routines which contain the actual “trap” instructions.
The error indicators are reset;
The user mode instruction which caused the trap is retrieved and all but the least significant six bits are masked off. The result is used to select an entry from the array of structures, “sysent”. The address of the selected entry is stored in “callp”;
The “zeroeth” system call is the “indirect” system call, in which the parameter passed is actually the address in the user program data space of a system call parameter sequence.
Note the separate uses of “fuword” and “fuiword”. The distinction between these is unimportant on the PDP11/40, but is most important on machines with separate “i” and “d” address spaces;
“i=077” simulates a call on the very last system call (2975), which results in a call on “nosys” (2855), which results in an error condition which will usually be fatal for the user mode program;
The number of arguments specified in “sysent” is the actual number provided by the user programmer, or that number less one if one argument is transferred via r0. The arguments are copied from the user data or instruction area into the five element array “u.u_arg”. (From “sysent” (Sheet 29) it would seem that four elements would have been sufficient for “u_area[ ]” – is this an allowance for future inflation?);
The value of the first argument is copied into “u.u_dirp”, which seems to function mainly as a convenient temporary storage location;
“trapl” is called with the address of the desired system routine. Note the comment beginning on line 2828;
When an error occurs, the “c-bit” in the old processor status word is set (see line 2658) and the error number is returned via r0.