Modern computer systems have a layered organization, which each layer either using the services of, or being physically built from, entities on the level directly below it.
Layer | People | Domain |
---|---|---|
Application Programs | Application Programmers | Software |
System Utility Programs | System Programmers | |
Operating System | ||
I/O System (BIOS) | ||
Computer System | Computer Engineers | Hardware |
CPU | Computer Architects | |
Memories, Logic Circuits, Flip-Flops, Gates | Logic Designers | |
Transistors, Diodes, Resistors, Power Supplies | Materials Scientists |
The computer systems we build today feature programmable processing units which interact with a number of devices, each controlled by an I/O controller, and using memory.
Clearly, this picture is an oversimplification. Each CPU can have one or more cores. There may be additional kinds of processors, including GPUs and TPUs. Memory itself is layered (cache memory, main memory, secondary memory). Machines themselves are networked, giving the appearance of one large machine made up of smaller ones.
Devices are roughly classified into input devices, output devices and storage devices. Examples include:
Devices | ||
---|---|---|
Input Devices | Output Devices | Storage Devices |
Keyboard Mouse Light Pen Joystick Joyswitch Trackball Tablet Track Pad Surface Digitizer Microphone Voice Recognizer Scanner Fingerprint Scanner Card Reader Paddle Game Controller Data Glove Wand Video Camera Eye Tacker Motion Sensor |
Screen Television Printer (2D or 3D) Plotter Film Recorder Projector Hologram Generator Robot Arm Speaker Headphones Voice Synthesizer Card Punch |
Disk Drive CD Drive DVD Drive USB Flash Drive Solid State Drive (SSD) Tape Drive |
Software can be roughly divided into systems software and applications software. The dividing line is fuzzy, but the basic concepts are:
Applications Software | Systems Software |
---|---|
Written for people | Written for computers |
Deals with human-centered abstractions like customers, products, orders, employees, players, users | Deals with computer-centered concepts like registers and memory locations |
Solves problems of interest to humans, usually in application areas like health care, game playing, finance, etc. | Controls and manages computer systems |
Concerned with anything high-level | Concerned with data transfer, reading from and writing to files, compiling, linking, loading, starting and stopping programs, and even fiddling with the individual bits of a small word of memory |
Is almost always device or platform independent; programs concentrate on general-purpose algorithms | Deals with writing device drivers and operating systems, or at least directly using them; programmers exploit this low-level knowledge |
Is often done in languages like JavaScript, Perl, Python, Ruby, Lisp, Elm, Java, and C# that feature automatic garbage collection and free the programmer from low-level worries | Is often done in assembly language, C, C++, and Rust where programmers have to manage memory themselves |
Is done in languages that generally have big fat runtime systems | Generally feature extremely small run-time images, because they often have to run in resource constrained environments |
If done properly, can be very efficient: good garbage collection schemes allow much more efficient memory utilization than the usual memory micro-management common in C programs | If done properly, can be very efficient: you can take advantage of the hardware |
There are different levels of programming languages: High-level languages, Assembly Languages, Machine Languages. A machine language is what a processor runs. It’s pure binary. A assembly language has instructions that map one-to-one to machine language instructions. A high-level language uses far more abstract concepts to describe computations. Often, people write in a high-level language, which a compiler translates to assembly language, which an assembler translates into machine language:
Here’s an example. Start with this C++ function:
long example(long x, long y, long z) { if (x > y) { return x * y - z; } else { return (z * y) * y; } }
The compiler produces this assembly language:
_Z7examplelll: cmp rdi, rsi jg .L5 imul rdx, rsi mov rax, rdx imul rax, rsi ret .L5: mov rax, rdi imul rax, rsi sub rax, rdx ret
which becomes this in machine language:
4839F7 7F0C 480FAFD6 4889D0 480FAFC6 C3 4889F8 480FAFC6 4829D0 C3
You are better learning assembly than not learning it. For one thing, it enables a more intimate and hands-on study of computer systems:
Assembly is a mechanism by which a programmer can learn details of computer hardware, CPU components, memory organization, and the interactions among these elements of computer architecture.
— Brian Hall and Kevin Slonka
Other reasons:
Here are things to study to get a good well-rounded familiarity with computer systems and systems programming:
Wikipedia has articles on systems programming and system software.
Things to browse showing aspects of computer systems might affect your life: