Where software meets hardware..

Oliver Fromme olli at lurza.secnetix.de
Thu Jun 21 12:56:36 UTC 2007

Mark Jayson Alvarez wrote:
 > Good day! I could have sent this to questions at freebsd.org but I know
 > it will get treated as irrelevant topic as well. Just trying my luck
 > here though.

Actually this is most appropriate on the "chat" list.
I've redirected replies there.

 > I have a cousin who's taking up a programming course. He doesn't have
 > background with programming nor an in depth understanding of how the
 > computer works.  I tried explaining him that it all started with
 > abacus, and that people wanted to use something that could make their
 > arithmetic life easier and that Charles Babbage tried automating this
 > manual calculator with his steam engine or some sort... and that...

Actually Charles Babbage designed a complex mechanical
computing machine (with lots of gearwheels etc.), but
it only ever existed on paper.  Only small parts of it
have actually been built, but never the whole thing,
because it was too complex.  It would work in theory,
though.  :-)

 > This is how my programming teacher explains how a program gets
 > executed.  First you compile it into a machine readable code, then
 > the operating system writes it in the memory, and finally the CPU
 > fetches it and it finally gets toasted by the electricity flowing on
 > the CPU's surface.  It doesn't make things clearer though.:-(

That's pretty close to the truth, actually.

 > I really don't get it. Can you in a very simple sentence explain to
 > me how and where a software program

I'm afraid the interactions between memory, processor
(CPU) and software is a complex thing which cannot be
explained in a single simple sentence.  I'll try to
explain a bit ...

A processor is able to execute instructions which are
called "machine code".  Basically it's a sequence of
bytes stored in memory (RAM).  The processor fetches
byte after byte from memory and executes the commands
that they represent.  Such commands include:  "load
a number from memory into a processor register", or
"add these two processor registers and store the result
in memory", or "check whether this value is zero, and
if it is, then jump to a specified address in memory
instead of continuing with the following instruction".
It's possible to have loops, subroutines, interrupt
routines and other things, but the details aren't
important in order to get a basic understanding.

Of course, most programmers don't write that machine
code directly.  It's efficient for the processor to
execute, but it's inconvenient for a human programmer
to write.  A programmer usually writes programs in a
higher-level language, such as C.  Then a tool called
compiler is used to convert that "source code" into
"machine code" that can be executed by the processor.
The result is an executable file stored on disk (also
called a "binary").

When a binary is about to be executed, the operating
system (such as FreeBSD) loads it from disk into RAM
where its byte stream can be executed by the processor.

Of course in reality it's more complicated, but the
above are the very basic and low-level things that

Device drivers are somewhat different.  They're normal
binaries, too (usually compiled from source code, too),
but they're loaded once when the operating system boots
the computer, or once when the appropriate kernel
module is loaded.  Many device drivers are interrupt-
driven.  When an external event occurs, such as a
packet arriving on a network interface, or the user
pressing a key on the keyboard, the hardware device
signals an interrupt to the processor (basically a
connector pin on the processor is set from "low" to
"high", i.e. from 0 V to 5 V or similar).  The processor
stops whatever it is doing right now, fetches the
address of an "interrupt handler routine" from memory,
and jumps to that address (i.e. starts executing
instructions from that address).  That handler is
usually installed in memory by the operating system.
The code checks which device caused the interrupt,
and then executes the appropriate routine in the
corresponding device driver.  When it's finished,
a "return" instruction is executed, which causes the
processor to resume whatever it was doing before the
interrupt occured.

 > Does it have anything to do with the bios?

The BIOS is also simply a piece of software, stored
in a chip on the mainboard.  It initializes the hard-
ware right after the machine is switched on, and
arranges for the operating system to be booted from
the disk (or from other kind of media if supported).
After the operating system takes control of the box,
the BIOS is not used anymore at all.  (There are
certain exceptions, but lets forget about them for

Booting is usually a multi-stage process, i.e. first
the BIOS loads a tiny boot loader from the first
sector of the disk (the MBR == master boot record),
then the code contained in the MBR loads the
operating system's first stage boot loader and so
on.  All of those stages still use BIOS routines
to access the disk.  The last stage (in FreeBSD
that's /boot/loader) loads the actual OS, i.e. the
kernel and modules that are required to boot the OS.
The kernel has its own device drivers for disks and
other media, so it doesn't use the BIOS anymore.

 > I told my cousin, that someday he will be a real programmer and that
 > even if he will be dealing only with java, html, animation and all
 > sorts of high level programming stuffs,

It should be pointed out that HTML is not a programming
language.  ;-)

 > in the spirit of open source (and freebsd of course), it's better
 > that he knows exactly how a program interacts with the physical
 > computer.

Well ...  It depends.  As a high-level programmer, it
is good to know how machine code works and how the
compiler generates it, because it also enables you
to write more efficient programs.  That's especially
true for kernel source and device drivers.

On the other hand, both processors and compilers
become more and more complex and advanced, and newly
designed higher-level languages (such as Python)
increase the "distance" between machine code and the
source code that people write, so there is less

Therefore I think that nowadays it is more important
to learn software design, how to develop efficient
algorithms, learn a bit about computational complexity
(for example, when and why is quicksort faster than
bubblesort) etc.

At university there was a teacher who said that you
should learn as many different programming languages
as possible, at least one of every kind, i.e. one of
the "classical brace languages", such as C, at least
one object-oriented language (e.g. Smalltalk, Eiffel),
one functional language (Haskell or OCaml), one
assembly language (no matter which one) and so on.
The more the better.

Best regards

Oliver Fromme, secnetix GmbH & Co. KG, Marktplatz 29, 85567 Grafing b. M.
Handelsregister: Registergericht Muenchen, HRA 74606,  Geschäftsfuehrung:
secnetix Verwaltungsgesellsch. mbH, Handelsregister: Registergericht Mün-
chen, HRB 125758,  Geschäftsführer: Maik Bachmann, Olaf Erb, Ralf Gebhart

FreeBSD-Dienstleistungen, -Produkte und mehr:  http://www.secnetix.de/bsd

"With sufficient thrust, pigs fly just fine.  However, this
is not necessarily a good idea.  It is hard to be sure where
they are going to land, and it could be dangerous sitting
under them as they fly overhead." -- RFC 1925

More information about the freebsd-chat mailing list