EC-10.1 The Hardware and Software Boundary

en

What this is and why it exists

Computer organisation is usually taught as one machine in detail. That leaves a reader who has finished it unable to say which parts of what they learned were universal and which were that machine.

This topic draws the line instead. On one side is the promise a processor makes to software. On the other is the freedom it keeps underneath.

Everything else in this module lives on one side of that line or the other, and knowing which is the point.

The vocabulary

  • Instruction set — the set of instructions, registers and behaviours a processor promises to software.
  • Microarchitecture — how a particular processor actually implements that promise.
  • Register — a location inside the processor where arithmetic happens.
  • Calling convention — an agreement about argument passing and which registers survive a call.
  • Caller-saved register — one the called function may destroy, so the caller saves it if needed.
  • Callee-saved register — one the called function must restore before returning.
  • Privileged mode — an execution mode in which restricted instructions and memory are available.
  • Linker — the tool that combines compiled pieces and resolves addresses between them.
  • Loader — the part of the system that places a program in memory ready to run.

The mental model

The instruction set is a contract. These instructions exist, these registers exist, and this is what each one does. Any processor that keeps that promise runs the same program, however differently it is built inside.

That single idea explains a great deal of industrial history. It is why a program compiled twenty years ago still runs, and why several companies can sell processors that run each other's software. It is also why a design can be rebuilt from scratch without breaking anything above it.

What the hardware keeps for itself is everything below the promise. Pipeline depth. Cache sizes. How many instructions start in one cycle. The order they actually finish in. None of it is visible to correct software, and all of it changes between one generation and the next.

That freedom is the reason one instruction set survives decades of redesign. It is also why performance figures are properties of a particular chip, not of the instruction set it implements. People get that distinction wrong constantly.

Now the fact that shapes nearly every performance idea in the module. A register is read in a fraction of a cycle. Main memory takes hundreds of cycles. The ratio is enormous and it has grown, not shrunk, for decades.

Almost everything a modern processor does is an attempt to hide that gap rather than to close it. Caches hide it by keeping recent data close. Pipelining and out-of-order execution hide it by finding other work to do while waiting. Prefetching hides it by guessing what will be wanted.

The calling convention is the first thing on the software side of the line. It is an agreement rather than hardware. It fixes where arguments go, where the result comes back, which registers a called function may destroy, and how the stack is arranged.

Because it is an agreement, it can differ between operating systems on the same processor. Code from two compilers works together only when they agree on it. Understanding it is what makes a stack frame readable and a crash inside a library diagnosable.

Privilege is the last hardware idea in the topic and it is a small one with large consequences. Some instructions and some memory regions are available only in a privileged mode. Ordinary programs run unprivileged and ask the operating system for anything else.

That one distinction is what lets an operating system stop one program from reading another's data. It is the foundation under every protection mechanism above it. Without it there is no isolation, however careful the software.

Finally, the three tools people confuse. The compiler turns source into machine code with addresses left unresolved. The linker combines those pieces and fills the addresses in. The loader places the finished program in memory when it runs, and may relocate it again.

Knowing which one to suspect saves hours. An undefined symbol is a linker problem. A crash on the first instruction is usually a loader or startup problem. Wrong arithmetic is a compiler or a source problem.

What you should now be able to explain or do

  • State what the instruction set promises and what the implementation is free to change.
  • Explain why performance is a property of a chip rather than of an instruction set.
  • Describe the register-to-memory gap and name three mechanisms that hide it.
  • Say what a calling convention fixes and why two compilers must agree on one.
  • Explain what privileged mode makes possible.
  • Attribute a build or run failure to the compiler, the linker or the loader.

Check yourself

The instruction set. They can differ in every internal detail, because none of that is part of the promise made to software.

Because speed comes from the implementation. Pipeline depth, cache sizes and issue width are all invisible to software and all differ between chips keeping the same promise.

A caller-saved register may be destroyed by the function you call, so you save it first if you still need it. A callee-saved register must be restored by the function before it returns.

The linker. The compiler produced code with that address unresolved, and the linker could not find anything to resolve it to.

Go deeper

Back to The Hardware and Software Boundary: work through the checklist