Section 11.6
OS modes and instructions

At this stage you should be wondering how these special registers, the base address register and the field length register, get set. In the IBM world, how do the memory keys get changed? It is not enough to say that the operating system somehow does it, because the operating system is just another program, using the same ALU and the same instruction set as user programs, right?

Well, not exactly. True, the operating system is just a program, but it does have access to more instructions than user programs. In order to make multiprogramming work, the hardware must have at least two operating modes:

privileged mode Special instructions can be done while in this mode, so only OS code can run in privileged mode. Certain registers that cannot be read or written in user mode can be changed by the OS while in this mode.
user mode User programs operate in this unprivileged state. They cannot change the base address or field length registers, nor can they send signals to I/O controllers. They cannot execute certain other instructions, especially HALT.

There is a flip-flop in the CPU that says whether or not the machine is running in privileged or user mode. If a user program attempts to execute a forbidden instruction or if it attempts to access one of the special registers, an error is signaled and the program is killed, usually after another nastygram from the OS.

The mode flip-flop can be changed from unprivileged mode to privileged mode at any time. The OS can issue an instruction to do this and it must make sure the machine is in unprivileged before it hands control back to a user program. But how does the mode flip-flop ever get set back to privileged once it is in unprivileged mode?

Any one of the fatal errors we have discussed so far will cause the mode to automatically change back to privileged so that the OS can clean up after the offending job. But there needs to be a kinder, gentler way to change back, and it is called a trap or supervisor call. An unprivileged machine instruction does it. Even user programs can call it, and in fact they must since this is the only way they can voluntarily return the system's state to privileged mode.

Many computer systems call this instruction trap and use a mnemonic like TRP. IBM mainframes call it a supervisor call, since they sometimes call their operating systems the supervisor. Their mnemonic is SVC. We will use the term trap from here on.

One of the standard ways of viewing the operating system is as a service provider. This is in contrast to viewing it as a governor or controller, although it must be this, too. Thinking of the operating system as a bundle of services and subroutines that all user programs can, and in fact must, use makes it easier to visualize what a trap does and why it is needed. The services provided by an operating system are many and varied. Here is a small list:

In some ways the operating system is merely a huge collection of subroutines. There is one for ending a job's existence. Another subroutine exists for sending and receiving messages and yet another for creating children programs and so forth. User programs call these subroutines when they need them, like any program calls a subprogram when it needs it. (Remember that the terms subroutine, subprogram, function and procedure are all synonymous in this discussion.) There must also be a tiny core of program in the OS that starts the whole system going but once it is going, it is more or less in the hands of the user programs. After all, OS's exist for the pleasure and benefit of the user programs, don't they?

ASIDE: If you have never seen the movie 1983 "Tron," you should. It is a fascinating visual joyride through the interior or a computer. The operating system is called the MCP, Master Controlling Program, and it acts like one! The main question that the inner components ask each other is "Do you believe in users?" "Tron" is a neat way to gain an appreciation of computer architecture.

The fly in this ointment is that ordinary programs can make subroutine calls to any memory address in their own code, but we cannot allow user programs to call the operating system at any old location. The operating system must be called only at well-defined entry points that correspond to published subroutines. A call to the operating system is called, not surprisingly, a system call.)

One of the weaknesses of the von Neumann architecture we have been studying all along is that a CAL instruction can specify any address as its jump target, although we almost always want that address to correspond to the beginning of a subprogram. User programs cannot be allowed to jump to any address because they could easily bypass security checking. In fact, a user program could jump to an instruction that changes the mode to privileged and then it would be able to do anything. This is exactly the kind of loophole that hackers seek when they break into systems, because they can't do much until they get the full privileges of root (also called superuser.)

The TRP instruction is like a CAL instruction except that it specifies a service number instead of a memory address. This service number is just the numerical form of the system call, which is the published subroutine that the OS makes available to users. Once the operating system gets control, it looks the service number up in a table and branches to the actual subroutine that implements that service. In this way, no user program can jump to a location that the operating system doesn't want it to; it can only jump to the entry point of the service subroutine. Generally, the first thing that the service subroutine does is to check the user program's "papers," i.e. it verifies that the request is in order, all the parameters are okay, and that this user has permission to call this routine. If not, then a system error will abort the program. (This is termed an abend in IBM-ese, which is a contraction of "abnormal end.")

Fig. 11.6.1 shows this calling of a system subroutine via a TRP. The call is equivalent to the C version of the UNIX system call read:

n = read(fd, buf, m);

which requests the operating system to read up to m bytes from the I/O device pointed to by fd and put it into the character array buf.


Fig. 11.6.1: Read system call; PUSH #3 stands for 3 parameters;
TRP means to call system call #2 (which is read)

This mechanism or something very similar to it is used in most multiprogrammed systems. It is interesting to see how there is a continual interplay between hardware designs and the uses to which the hardware is put. For example, if computers had continued to be used by just one person at a time, none of this stuff for protection and relocation would have been needed. In Chapter 13 we will see how another user trend influenced hardware, namely the need to run very large programs or use more memory than is actually available. This is how virtual memory came about.