“main” uses both “fuibyte” and “fuiword”. Since the former is more complicated in a non-essential way, we leave it to the reader, and concentrate on the latter.
“fuiword” is called (1602) when the system is running in kernel mode with one argument which is an address in user address space. The function of the routine is to fetch the value of the corresponding word and to return it as a result (left in r0). However if an error occurs, the value –1 is to be returned.
Note that with “fuiword”, there is an ambiguity which does not occur with “fuibyte”, namely a returned value of –1 may not necessarily be an error indication but the actual value in the user space. Convince yourself that for the way it is used in “main”, this does not matter.
Also the code does not distinguish between a “bus timeout error” and a “segmentation error”.
The routine proceeds as follows:
The argument is moved to r1;
“gword” is called;
The current PS is stored on the stack;
The priority level is raised to 7 (to disable interrupts);
The contents of the location nofault (1466) are saved in the stack;
“nofault” is loaded with address of the routine “err”;
An “mfpi” instruction is used to fetch the word from user space.
If nothing goes wrong this value will left on the kernel stack.
The value is transferred from the stack to r0;
The previous values of “nofault” and PS are restored;
Now suppose something does go wrong with the “mfpi” instruction, and a bus time-out does occur.
The “mfpi” instruction will be aborted. PC will point to the next instruction (0857) and a trap via vector location 4 will occur;
The new PC will have the value of “trap”. The new PS will indicate:
present mode = kernel mode
previous mode = kernel mode
priority = 7;
The next instruction executed is the first instruction of “trap”. This saves the processor status word two words beyond the current “top of stack”. (This is not relevant here.);
“nofault” contains the address of “err” and is non-zero;
Moving 1 to SR0 reinitialises the memory management unit;
The contents of “nofault” are moved on top of the stack, overwriting the previous contents, which was the return address in “gword”;
The “rtt” returns, not to “gword” but to the first word of “err”;
“err” restores “nofault” and PS, skips the return to “fuiword”, places –1 in r0, and returns directly to the calling routine.