Look what I found in my closet:

Motorola 68HC11 on an eval board made by Axiom Manufacturing
This is my old Motorola 68HC11 microcontroller board. Here's a close up photo of the microcontroller itself:

Motorola 68HC11 Microcontroller IC
For those who aren't familiar with these terms, a microcontroller is basically a computer on a chip. They are often very tiny and low powered, and are ubiquitous whether you realize it or not.
This is what I learned assembly language and machine language on in 2001. Machine language is basically the language of the CPU. Everything that a computer runs is in machine language. All other programming languages are compiled or interpreted down to machine code. Assembly language is a bare bones one-to-one mapping from machine codes to symbols that are barely human-readable.
I had encountered assembly language before 2001 in 3D game code, but I didn't totally understand it, especially registers.

Wolfenstein 3D
The reason I was reading 3D game code: After playing Wolfenstein 3D in the 1990s, I wanted to make similar games. So I got a book about ray casting engines. Ray casting was a method of generating the pseudo 3D graphics of early "3D" games; it was used because it was fast enough to run on those slow processors we had back then (and the GPU race had only just begun). There were a lot of tricks involved, like using trig look-up tables and sections of assembly code.
The reason they used assembly language in middle of high level code for games is that it's an old-fashioned optimization trick--make the slowest part of the code go faster by writing it in a lower-level language. The premise is that the compiler, for instance of C++, will not make code as fast as your own version in assembly language. Compilers are very good nowadays, so this is often not worth the effort.
Unfortunately, by the time I was learning about ray casting in the late 1990s, the gaming world had already evolved beyond that and started using BSP trees and polygonal 3D objects. I did start playing with BSP trees in 2001 by making a little Java 3D program that used BSP trees to lay out the walls (it was called The Garbage Collector, which is a joke).

title screen from a small Java game I made

screenshot from The Garbage Collector game
And then in 2002 I was playing with polygonal 3D rendering by making a multiplayer (client-server TCP) 3D boat shooting game using Direct3D (part of DirectX) for graphics.

screenshot from Smoke on the Water, my little multiplayer 3D boat shooting game
It didn't have much of an engine--if I recall correctly, I did a minimal amount of culling and then threw all the objects at Direct3D to render. I was also trying to make my own design of an octree based engine but it never amounted to much.
Education-wise, I suspect that learning assembly and machine language for a relatively simple architecture like an 8-bit microcontroller is much better than learning on a more complicated architecture like Intel x86. I tutored students at NHTI for 68HC11 and Northeastern University for x86. I found that either way, assembly language was quite difficult for a lot of students to learn--and even comprehend. But it was far worse with x86.
And, with an embedded platform, the labs can be set up so you actually make lights blink and motors move. That's way more awesome then just seeing some debug text print out on a console. It also seems to force people into the mindset of understanding what layers they are dealing with in computer architecture better and isolate their development realm (e.g. writing code in a text editor and cross-compiling) from the world of the computer processor loading the machine code and executing it.
If you want to see what the 68HC11 assembly code looks like, here you go:
(Unfortunately the <pre> tag doesn't work properly for line breaks on this website, so I will give an incomplete screenshot of the code in an editor instead of text.)

I wrote this code for for an exercise to control a stepper motor with gray code. The motor was small and low-power enough to be run directly off of an HC11 output. The program was a J-K flip-flop circuit emulator (it could actually emulate any 4-state counter if one modified the states in the data segment). It took an input from a function generator to define the frequency which determined the speed of the motor.
One of the most popular ways to control motors and other analog devices is with PWM (Pulse Width Modulation). Here is an example of PWM motor control that I wrote in 68HC11 assembly. Skip to the next section for my explanation of PWM.
(Unfortunately the <pre> tag doesn't work properly for line breaks on this website, so I will give an incomplete screenshot of the code in an editor instead of text.)


For those who want a simple explanation of PWM: Imagine flipping a light switch on and off a thousand times per second. But sometimes you leave it on longer or off longer. For example, you have it on 700 times but off only 300 times in that one second. The overall effect is that the light is on at 70% brightness during that time.
PWM is like that. Imagine hooking your switch to a motor. If you switch it with 70% ONs the motor will spin at 70% full speed.
The other key concept is that PWM is typically used as an interface between the digital world of the computer and the analog worlds of motors. A computer processor deals with ones and zeroes--ONs and OFFs. There are outputs on computers for instance on a microcontroller like the 68HC11 in this article. The ones and zeroes are represented on those outputs with HIGH and LOW voltages. All the other devices connected will use the same standard for what is HIGH and what is LOW, e.g. 5 volts as HIGH and 0.0 volts as LOW. (That's a bit simplified but I won't bore you with other details right now).
So the problem is how to get those HIGHs and LOWs to control a motor, which just wants voltage. If it's a tiny motor it can run directly off of the logic voltage (e.g. 5 V), but that's not generally a good option. In fact, you usually want the motor power lines isolated from the computer lines.
So PWM (remember, switching really fast) is used. The computer outputs a square wave (HIGHs and LOWs) to a switch, which switches the power from another source (e.g. a battery) into the motor. The higher the percentage of ones (HIGHs) coming out of the computer, the faster the motor goes. Obviously if there is something heavy attached to the motor rotor, it won't actually go faster, but it will try.
This was really awesome when I learned about it (and the aforementioned gray code exercise), because up until then my programming was not able to interface to motors. I could make a motor go by connecting a battery directly to the leads, and even add in a mechanical switch, but a single speed motor is not fun for very long.
Once you start learning how to get motors spinning from computer code, and also get inputs from sensors into the code, you start realizing that basic hobbyist robotics isn't that difficult...
Of course, if you can't code, then I guess you will be stuck doing the typical undergraduate mechanical engineering student trick of touching a wire from a battery directly to a motor in the contraption they just screwed together and watching the chaos unfold as it flings itself around the lab until they let go of the wire.

Motorola 68HC11 on an eval board made by Axiom Manufacturing
This is my old Motorola 68HC11 microcontroller board. Here's a close up photo of the microcontroller itself:

Motorola 68HC11 Microcontroller IC
For those who aren't familiar with these terms, a microcontroller is basically a computer on a chip. They are often very tiny and low powered, and are ubiquitous whether you realize it or not.
This is what I learned assembly language and machine language on in 2001. Machine language is basically the language of the CPU. Everything that a computer runs is in machine language. All other programming languages are compiled or interpreted down to machine code. Assembly language is a bare bones one-to-one mapping from machine codes to symbols that are barely human-readable.
I had encountered assembly language before 2001 in 3D game code, but I didn't totally understand it, especially registers.
An Aside on 3D Game Programming

Wolfenstein 3D
The reason I was reading 3D game code: After playing Wolfenstein 3D in the 1990s, I wanted to make similar games. So I got a book about ray casting engines. Ray casting was a method of generating the pseudo 3D graphics of early "3D" games; it was used because it was fast enough to run on those slow processors we had back then (and the GPU race had only just begun). There were a lot of tricks involved, like using trig look-up tables and sections of assembly code.
The reason they used assembly language in middle of high level code for games is that it's an old-fashioned optimization trick--make the slowest part of the code go faster by writing it in a lower-level language. The premise is that the compiler, for instance of C++, will not make code as fast as your own version in assembly language. Compilers are very good nowadays, so this is often not worth the effort.
Unfortunately, by the time I was learning about ray casting in the late 1990s, the gaming world had already evolved beyond that and started using BSP trees and polygonal 3D objects. I did start playing with BSP trees in 2001 by making a little Java 3D program that used BSP trees to lay out the walls (it was called The Garbage Collector, which is a joke).

title screen from a small Java game I made

screenshot from The Garbage Collector game
And then in 2002 I was playing with polygonal 3D rendering by making a multiplayer (client-server TCP) 3D boat shooting game using Direct3D (part of DirectX) for graphics.

screenshot from Smoke on the Water, my little multiplayer 3D boat shooting game
It didn't have much of an engine--if I recall correctly, I did a minimal amount of culling and then threw all the objects at Direct3D to render. I was also trying to make my own design of an octree based engine but it never amounted to much.
Assembly Language Education
Education-wise, I suspect that learning assembly and machine language for a relatively simple architecture like an 8-bit microcontroller is much better than learning on a more complicated architecture like Intel x86. I tutored students at NHTI for 68HC11 and Northeastern University for x86. I found that either way, assembly language was quite difficult for a lot of students to learn--and even comprehend. But it was far worse with x86.
And, with an embedded platform, the labs can be set up so you actually make lights blink and motors move. That's way more awesome then just seeing some debug text print out on a console. It also seems to force people into the mindset of understanding what layers they are dealing with in computer architecture better and isolate their development realm (e.g. writing code in a text editor and cross-compiling) from the world of the computer processor loading the machine code and executing it.
Making Motors Move
If you want to see what the 68HC11 assembly code looks like, here you go:
(Unfortunately the <pre> tag doesn't work properly for line breaks on this website, so I will give an incomplete screenshot of the code in an editor instead of text.)

I wrote this code for for an exercise to control a stepper motor with gray code. The motor was small and low-power enough to be run directly off of an HC11 output. The program was a J-K flip-flop circuit emulator (it could actually emulate any 4-state counter if one modified the states in the data segment). It took an input from a function generator to define the frequency which determined the speed of the motor.
Making Motors Move with PWM
One of the most popular ways to control motors and other analog devices is with PWM (Pulse Width Modulation). Here is an example of PWM motor control that I wrote in 68HC11 assembly. Skip to the next section for my explanation of PWM.
(Unfortunately the <pre> tag doesn't work properly for line breaks on this website, so I will give an incomplete screenshot of the code in an editor instead of text.)

What is PWM?

For those who want a simple explanation of PWM: Imagine flipping a light switch on and off a thousand times per second. But sometimes you leave it on longer or off longer. For example, you have it on 700 times but off only 300 times in that one second. The overall effect is that the light is on at 70% brightness during that time.
PWM is like that. Imagine hooking your switch to a motor. If you switch it with 70% ONs the motor will spin at 70% full speed.
The other key concept is that PWM is typically used as an interface between the digital world of the computer and the analog worlds of motors. A computer processor deals with ones and zeroes--ONs and OFFs. There are outputs on computers for instance on a microcontroller like the 68HC11 in this article. The ones and zeroes are represented on those outputs with HIGH and LOW voltages. All the other devices connected will use the same standard for what is HIGH and what is LOW, e.g. 5 volts as HIGH and 0.0 volts as LOW. (That's a bit simplified but I won't bore you with other details right now).
So the problem is how to get those HIGHs and LOWs to control a motor, which just wants voltage. If it's a tiny motor it can run directly off of the logic voltage (e.g. 5 V), but that's not generally a good option. In fact, you usually want the motor power lines isolated from the computer lines.
So PWM (remember, switching really fast) is used. The computer outputs a square wave (HIGHs and LOWs) to a switch, which switches the power from another source (e.g. a battery) into the motor. The higher the percentage of ones (HIGHs) coming out of the computer, the faster the motor goes. Obviously if there is something heavy attached to the motor rotor, it won't actually go faster, but it will try.
Why was this Exciting?
This was really awesome when I learned about it (and the aforementioned gray code exercise), because up until then my programming was not able to interface to motors. I could make a motor go by connecting a battery directly to the leads, and even add in a mechanical switch, but a single speed motor is not fun for very long.
Once you start learning how to get motors spinning from computer code, and also get inputs from sensors into the code, you start realizing that basic hobbyist robotics isn't that difficult...
Of course, if you can't code, then I guess you will be stuck doing the typical undergraduate mechanical engineering student trick of touching a wire from a battery directly to a motor in the contraption they just screwed together and watching the chaos unfold as it flings itself around the lab until they let go of the wire.
Image Credits:
- Samuel H. Kenyon
- Samuel H. Kenyon
- http://www.schmoozd.com/2012/05/10/happy-birthday-wolfenstein-3-d/
- Samuel H. Kenyon
- Samuel H. Kenyon
- Samuel H. Kenyon
- Samuel H. Kenyon
- Samuel H. Kenyon
- http://www.green-house-cleaning-tips.com/2012/05/some-great-energy-savin...




This is rather important because assembly language at its purest is a separate level of programming from machine code. Of course it maps to machine code, but it exists in a little world of its own with access to a whole field of abstract symbols. You can easily use ;an assembler to manipulate data just for fun without creating a single instruction.
Anyway, I'm glad ;I am not the only one who grapples with assembly language. But I am an ancient fossil and no-one gives a **** how I waste my remaining time on the planet. If you learned assembler; in 2001, you are still young enough to make something of your life if you want to! Wipe your assemblers from your computers. Destroy the source code lest you are tempted. It will be a hard journey but it is worth it. I'm too old - you have your life before you! Don't fritter it away on assembly language, I implore you.