ASM prolog (HelloWorld)

A project log for AVR Asm Exam

Doing the "exam" of the AVR assembly course

Michael MöllerMichael Möller 02/26/2021 at 20:190 Comments

Baby steps: I first wrote a small ASM in the given template, to do the hardware equivalent of HelloWorld - blink a LED (on pin 13 for the Arduino) Writing it took 5 minutes. Getting it to work took more of an hour.

Private project on Wokwi

This sidetracked my for a while: The way to copy a template to a private file on Wokwi ... yeah, needs an attempt or two. Also I had an issue with my browser (I think). Actually this was the first thing I did, create the empty projects for the C and ASM version respectivly, ie. with no code.

Assembler extensions and register addresses

Back to the LED (pin 13): That worked without any issues. No, not true, there is getting the definitions of PORTB included. (The assembler accepts some "C"syntax stuff, ie #include, and that line has to use C comments // instead of assembler ; ... mere details =:-0 ) AVR has the unusual property that most registers can be accessed by both as a memory-mapped register and via a special IO instruction (IN or OUT), but with different addresses. The "PORTB" define is for the memorymapped version, unless you include a special define or a macro to transform between the two. Room for confusion. The assembler says "out of bound value" if you're lucky when using the wrong address-type. So this version uses absolute numeric values.

Initializing the CPU

I experimented with this a while. Note that we run this without any C at all, so strictly speaking my program has to initialize stack and interrupt vectors. I did this, and I forgot this (ie both ways) and it made no difference. Looking at the object dump (In Wokwi type F1,a,s,s,return, view the sketch.lst file. It does NOT update with each compile!) I saw the assembler/linker sort of ignored my code and had included some other code. This (like all other items above) had been mentioned in the course, but sometimes you do not get the significance in the presentation.

So the long and short of it: The Arduino IDE and gcc in collusion create the interrupt vector table and initialization code for the stackpointer and thus preserves the "Upload a program" functionality to the Arduino board. (Upsetting the RESET vector may brick your CPU until you use a proper programmer)

Uri did point out that including a special routine would also automagically initialize variables (.data region) with nonzero values.

;;; "PONG" in AVR assembly - actually just turn LED13 ON

; V0.0.01 - just a quicky to get the tiniest assembly program running

.global main

.org 0            // this does the proper setup, wrt. interupt vectors
   jmp main       // without it, program lies and runs at location 0

.org 0x100 

  ; ==== Initialization =====
  ldi R16,0x20       ; Load bit 5
  out 4,R16          ; Direction bit: "output" for PortB, bit 5
  out 5,R16          ; Set it ON

  ; ==== "loop" ====
burn:  rjmp burn     ; Burn CPU, burn !

This version reduntantly creates a partial vector table. It is not "correct" but works. Also it does not blink the LED, it merly turns it on, but commenting out one of the "out" instruction shows that it is my code that turns it on.