In understanding the complexities of software development, let’s pause for a second and ask the question:
What is software?
The American Heritage Dictionary defines software as: written or printed data such as programs, routines, and symbolic languages, essential to the operation of computers.
This definition is mostly correct, but I would go a step further and say that software is anything that controls hardware. Software does not exist solely inside computers. Instead, software controls parts of your car, phone, toaster, oven, coffee maker, and just about any piece of electronic hardware you have in your home or workplace. A more complete definition of software would be:
Software is a set of hardware instructions and their representation, which we call programs.
Programs can be represented on punch cards, magnetic tapes, film, and other media. It is important to understand that software is a set of instruction, not the physical media on which it is recorded. Hardware, in contrast I would define it as:
Electronic hardware is anything that is electrical or current goes through.
Hardware consists of tangible objects such as: electronic circuits, input/output devices, cables and the likes and it does not consist of abstract ideas, algorithms or instructions. An intermediate form between hardware and software is called firmware and this is defined as:
Firmware is software embedded in hardware.
There is not much of a difference between software and firmware and in fact one could easily argue that they are equivalent. Firmware tends to be embedded into the hardware at manufacturing time and it is not expected to change for the lifetime of the hardware device. In addition, firmware is not lost when hardware looses power, whereas software, in the traditional sense, does not remain in memory when the hardware loses power.
If there is one key idea to consider about software, is that unlike other engineering projects, a software project tends to be more of a living project. A software project is much more like a plant that needs continuous watering in order to remain relevant. Because of the fast moving pace of computer hardware new versions of the same software, with new features, need to be developed and these new versions are most often built on top of previous versions. Contrast this with building a bridge, where once a bridge is built, it is good for many years, without major maintenance.
Understanding this key difference between a software project and most other engineering projects is important in order to appreciate the difficulty of building good software, as it will be highlighted in future chapters. Finally, a more thorough discussion of hardware and software definitions can be found in .
Hardware – Software Interaction
In most cases hardware and software are logically equivalent, in the sense that most algorithms can be implemented in either hardware or software and the decision which way to implement is solely up to the designer. In general, hardware tends to be extremely fast and can perform only a limited number of instructions, such as:
- Moves and Copies
The software uses these basic instructions to create complex algorithms. The software that directly controls hardware is called machine language. Because most machine languages are so simple, a lot of instructions are required to create even the simplest of algorithms. This can in turn become very tedious and laborious. Therefore software to generate this machine language was developed. This process of different software levels of development is highlighted in the following Figure :
Levels 1, 2, and 3 are numeric. Programs in these levels consist of a series of numbers, which are hard for people to interpret. Level 4 is the assembly language, which becomes a bit more user friendly. At this level the instructions contain words and abbreviations meaningful to people. Level 5 and higher is what most people think of when they think of software development. At this level you have the standard programming languages, such as C, C++, FORTRAN, etc. At levels higher than 5 you have virtual languages, such as .NET and Java. For comparison purposes, here is an example of an assembly language program (Level 4) and the equivalent C (Level 5).
The same program written in C would look approximately like this:
Notice how much more readable the program in C (Level 5) looks like when compared to assembly. The logic level is when you get down to the transistor level.
From left to right, we have a transistor (acting like an inverter), a NAND logic (high, high outputs low) and a NOR logic (either high produces a low). The resistors, the wiggly lines, are there to limit the current across the transistor’s gates, so that the transistors don’t burn. Interestingly enough, a transistor is used for power amplifiers as well. The difference is that in a power-amplifier, the transistor has to be biased such that it works in the transition region, whereas in the digital world, the transistor works in the saturated regions (high or low). More discussions on the transistor will be in another blog entry.
– D. Darian Muresan
 A. S. Tanenbaum, Structured Computer Organization. Prentice Hall, 1990.