Banner
    Languages, Assemble!
    By Samuel Kenyon | October 9th 2012 02:46 AM | 29 comments | Print | E-mail | Track Comments
    About Samuel

    Software engineer, AI researcher, user experience (UX) designer, actor, writer, atheist transhumanist. My blog will attempt to synthesize concepts...

    View Samuel's Profile
    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.

    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:

    1. Samuel H. Kenyon
    2. Samuel H. Kenyon
    3. http://www.schmoozd.com/2012/05/10/happy-birthday-wolfenstein-3-d/
    4. Samuel H. Kenyon
    5. Samuel H. Kenyon
    6. Samuel H. Kenyon
    7. Samuel H. Kenyon
    8. Samuel H. Kenyon
    9. http://www.green-house-cleaning-tips.com/2012/05/some-great-energy-savin...




    Comments

    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.
    Whilst that is pedantically correct it is somewhat misleading because, in practice, one is not usually interested in dis-assembling machine code back to assembly language but is much more interested in turning an assembly language program into machine code. Machine codes do map back one-to-one to symbolic assembly language but the reverse is not true. Assembly language typically permits a wide range of symbols only a handful of which end up defining the machine code; the rest are things like numbers which the programmer defines. Some may not even contribute to the code at all but simply facilitate a sanity check within the program. Even the name of a memory location may be defined by the programmer but the location itself is assigned by the assembler.

    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.
    SynapticNulship
     Assembly language typically permits a wide range of symbols only a handful of which end up defining the machine code; the rest are things like numbers which the programmer defines. 
    True. I can't explain everything about everything and keep this essay short and keep the interest of non-programmers.
    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.
    Reading assembly and dealing with registers directly still happens often even if you don't write in assembly, such as when debugging higher level programs. You won't be able to debug nontrivial problems with an embedded microcontroller if you are completely ignorant of how the processor works, what the registers are doing, and at least a vague notion of assembly language. That said, if everybody takes your advice, it just makes me that much more valuable. 
    As far as frittering away one's life, I actually don't spend much time on assembly language--a renaissance man does many things. But who are you to say what a person should be frittering their life away on?
    Gerhard Adam
    I think you've touched on one of the key difficulties with an assembly language; the need to understand the processor architecture on which you are coding.  Assembly language just appears to be arbitrarily difficult for performing routine tasks, so higher level languages make more sense.  However, when interacting with, or taking advantage of the architecture, then assembly language becomes more readily understandable as the vehicle for gaining your objective.
    SynapticNulship
    Indeed.
    when interacting with, or taking advantage of the architecture
    Hmm, I wonder when you last took advantage of the architecture in your code? Usually the hardware is a mass of "features" needing workarounds. Things like bottlenecks created by sharing an accumulator function with a pointer function :)  If you are lucky, the compliler knows about them and will optimize the code better than you ever could.

    The fact that manufacturers expose the architecture of their chips is more to do with the traditional split between software and hardware engineering than any inherent advantage in focussing on that level, which is neither the top level of system functionality nor the bottom level of semiconductor theory. There is nothing special about it except that we continue with the tradition of keeping "control" at this level while relinquishing the design of our chips to the guys in the factory and the design of our programming tools to faceless nerds.


    Look at it this way. You do not need to know or understand a device at the solid state level, nor at the transistor level, nor at the logic level, nor at the microcode level. Then comes the "architecture" of registers and instruction sets on top of which is your application machine code. You do not need to know or understand the system at the machine code level, nor at the assembly language level or at the intermediate semi-compiled level if using a HLL, nor even at the coding language level with its obscure syntax and mind-boggling arbitrary rules (e.g. inheritance).
     
    The only level that creative human beings should be interested is the level that they conceptualize the project in! This, of course, largely resides in the comments in a well-written program, or is hidden away in the programmer's head in badly-written ones. The programmer's job is to translate the requirements into functional abilities - preferably ones that the substrate already possesses. It is the easiest thing to do any-old-how and the hardest thing to get right. Admittedly, there are some application areas where saving a penny on the electronics will earn you the everlasting gratitude of your employer but for most stuff you may as well pay a few pence extra for a chip with some power to it and write in a decent language using the class libraries that thousands of previous programmers have toiled to create, or - horror of horrors! - create your own. That way you stand a chance of finishing a project in your own lifetime. Anything else is amateurish "garage engineering" and won't get past a technical audit if your field of application is the least bit critical.

    Where getting to know the hardware *is* important is where there are useful peripheral devices built into a microcontroller. But you still don't need to understand the architecture of the central processor and memory, you just need to understand the interface and the required protocol for driving the peripherals. Bit-banging is perfectly legitimate! But it's not assembly: the compiler should know that it is manipulating a hardware register directly and optimize the code to do so - it cannot skip a line just because the action is undone immediately afterwards.

    Pardon the polemic! Right on cue, something cropped up today to remind me how utterly dreadful assembly language really is :(


    Gerhard Adam
    All true unless you're writing operating system level code [and, of course, it depends on the platform you're programming for].

    I suppose I should have clarified that I wasn't referring to hardware architecture alone, but rather the architecture of the operating system/hardware synergy.
    I wasn't entirely serious about frittering one's life away! But it is true that I've used assembly far too much when a couple of lines of C could have replaced reams and reams of my dodgy code. I guess I was just talking to myself, really :/






    SynapticNulship
    Ha, I see.

    Context is key. If you want to make a full system and/or do something quickly, you need to use the appropriate level of language for each subsystem. The worst case is reinventing the wheel at a low level instead of focusing on the higher level new stuff that you originally intended to create.
    Very interesting, Samuel. This discussion helps me understand why I didn't 'get it' when I took the Intro to Assembly. I had been working with COBOL and the need to transfer my understanding to opcode just didn't happen.

    Gerhard Adam
    In COBOL, if you examine the PMAP, you'll see what assembler language instructions are generated by the compiler.
    SynapticNulship
    What prompted a COBOL programmer to take Intro to Assembly?
    Gerhard Adam
    Sooner or later they all want to go to the light ;)
    :-) Well in my case, I had to be pushed kicking and screaming all the way to that bright shining object. I was actually perfectly happy in my dark, dank, comfortable business enviro.

    Who knows the outcome if a person takes the left fork, all bright promise, instead of staying the dark course?

    Gerhard Adam
    Yes ... it is tempting to go over to the dark side.

    It begins innocently enough; write a COBOL program.  Then you think, I'll learn C, what's the harm.  Then one day you find yourself writing a shell script and then Java follows.  Suddenly before you know it ... your designing web pages.  :)
    Ye Gads! You can read me like an open book.

    Four years ago I stopped all of my internet madnesses. I had slowly built up to 56 websites that I either owned or managed for others. The magics of PHP were addictive. So addictive that I found myself ignoring important, real world, problems. A pox on SQL and CSS.

    If I had gone the FORTRAN route it's likely that I wouldn't have had time for that foolish internet thing.

    SynapticNulship
    I suffered one bout of PHP for awhile back in 2003 but thankfully it's never come back.
    Lately I have been thinking about getting [back] into web programming in order to have dynamic and interactive visualizations, esp. now that we have the tech to do it relatively easily without Flash.
    Hank
    This whole site is written in PHP.  See, it still sucks you in!
    Want more no-nonsense, independent science? Buy Science Left Behind
    PHP is a nifty language for building websites. This is a perfectly good example of the things than can be done. I've been out of the dynamics biz for a while. I still miss it sometimes.

    I've been doing some ugly things on the windoze platform lately. Mostly database, it's dreadful.

    MikeCrow
    I spend most of my day mucking around in sql, vB, MS Access and oracle databases, fortunately no web pages are involved (other than reading them).
    Never is a long time.
    SynapticNulship
    What is that in support of? Your bio indicates you might still do Product Lifecycle systems?
    MikeCrow
    Yes, Product Lifecycle Management Systems, you probably use something that came from a db I've worked on.
    Never is a long time.
    "I spend most of my day mucking around in sql, vB, MS Access and oracle databases"

    If you leave oracle out if it, then we have similar tasks.

    Completely off topic, but do you have any idea why M$ dropped vB and went the dot net stuff?

    MikeCrow
    No, but probably trying to be/take more advantage of the Interwebs.
    Never is a long time.
    What prompted a COBOL programmer to take Intro to Assembly?
    Sooner or later they all want to go to the light ;)
    Moths to a candle...
    It was required before you could take FORTRAN. At the time, late '60's, FORTRAN was being talked up as the road into the future. I happily stayed in the past. ;)

    SynapticNulship
    Apparently Axiom Manufacturing still makes this board (costs $112 now):

    http://www.axman.com/content/cme-11e9-evbu-single-chip-expanded-mode-development-system-mc68hc11e9-32k-sram-8k-eeprom
    Not sure where they are getting the obsolete HC11 chips...I guess that's the "gray market".

    The HC11 used to be popular in hobbyist and behavioral robotics in the 80s and 90s--it was used in the Handy Board (based off of boards used at MIT), and I think in Rodney Brook's MIT group at the AI lab that made the first subsumption robots, and it was used in Joe Jone's and Anita Flynn's excellent book Mobile Robots via the Rug Warrior (another MIT based kit). I read that book by borrowing it from the Northeastern University library...unfortunately it's quite pricey now (must be rare?) on the Internet (~$50). If you've never heard of Joe Jones, he's one of the primary inventors of the Roomba vacuuming robot.
    Gerhard Adam
    The inevitable consequences of this kind of programming:

    You might want to debug that one, Gerhard. When I click the OK, all I get is a string length of zero.

    Gerhard Adam
    You obviously hit the wrong key ...