[dorkbotpdx-blabber] assembler on the arduino?

Paul Stoffregen paul at pjrc.com
Mon Jan 28 14:06:29 EST 2008


Ultimately, your assembler is going to produce a .hex file which is an 
ascii encoded copy of the raw data that needs to be programmed into the 
MEGA168 chip.  All you need to do is write that code into the MEGA168 
chip, run it, and have some way to observe what it's doing so you can 
debug it (unless you never make any mistakes!)

There are 2 ways to program code into the MEGA168 chip.

#1: if the chip already has a bootloader programmed in, you can cause 
the bootloader to run and it will receive a download of code and write 
it into the chip (except for the portion which already has the 
bootloader, of course).  This is how the arduino is normally used.

#2: by connecting to a few pins, you can directly program code into any 
portion of the chip.  This is the only way to initially write the 
bootloader.  To do this, you need to buy or build hardware that 
manipulates the special programming pins.  For example: 
http://www.arduino.cc/en/Hacking/ParallelProgrammer  This is the way I 
have always programmed the Atmel AVR chips, though my custom-build 
hardware is quite different, the idea is the same.

There is actually another way, pretty much the same as #2, but many more 
pins are used for a small speed increase.  It's pretty much only used to 
program the chips in high volume production.

Usually, to observe what your code is doing, you'll send data via the 
UART to your PC serial port.  You can use the arduino software or any 
terminal emulator to view it.  You can also toggle output pins, which 
gives a lot less info but also takes a lot less time.  There are also 
expensive in-circuit emulator products that let for more or less 
directly observe stuff, but if you have the arduino, you're probably not 
going to buy one of those.


Also, there are 2 different approaches to assembly language.

Most commonly, people opt to write mostly in C and code tiny pieces in 
assembly.  C is a lot less work than assembly, so the reasoning goes 
that you can do everything "easily" in C that isn't speed critical, then 
only do the "hard work" on a few little sections.  This is true, 
however, the compiler will impose a lot of constraints on your assembly 
code.  Entry and exit from functions requires parameter passing using 
pre-defined registers (and the stack if more params), most other 
registers have to be saved if you use them, and so on.  Your freedom to 
allocate the registers is severely constrained.  While you don't have to 
write very much assembly this way, the bits you do write have many rules 
to follow.  That makes it more difficult and puts a lot of limits on you 
(basically the same limits the compiler has, though you're a lot smarter 
than the compiler and will still do a better job, even playing by its 
rules).

The other approach is to write everything in assembly.  Without the 
compiler's requirements, you have a lot more freedom.  Some people would 
say a lot more rope to hang yourself.  But just to give you an idea, the 
main difference (which matters most on the AVR) is that you get to 
decide about register allocation on a global scale.  You can, for 
instance, decide to dedicate several registers to some interrupt routine 
that needs a bunch of variables (quite common), rather than having to 
slowly (and with lots of extra code) push the registers onto the stack, 
load the variables from memory, and then to the reverse on exit from the 
interrupt.  All you have to do is simply not use those registers 
anywhere else (or disable interrupts, but if you're coding such high 
performance interrupt handlers, disabling interrupts for any length of 
time is probably the last thing you'll want to do).  There are a lot of 
ways to achieve much faster, much smaller code than is ever possible 
with the compiler, if it's never used anywhere and you don't have to 
obey its rules.


So, if you really want to do an all assembly approach the "hard way" (as 
Don will happily tell you I'm crazy to do), first try writing a very 
simple bit of assembly code to just toggle a pin in an infinite loop.  
It should be only a dozen bytes of output.  Then build that parallel 
port cable and try getting the MEGA168 chip to run it, using a 'scope or 
multimeter (DC volts 2.5 if it's toggling high/low rapidly at 50%) or 
even an LED to observe the pin.  Then try sending some bytes out the 
UART while watching via a terminal emulator.  Once you get to that 
stage, well, you'll be well on your way.

But in all likelihood, if your course is using the arduino, it may be 
other approach of using C with little bits of assembly.


-Paul





More information about the dorkbotpdx-blabber mailing list