Assembly code for creating interrupts vector on LPC2148 ARM processor-Collection of common programming errors

I’m going to remove the conditional code, since it just complicates things:

// Runtime Interrupt Vectors
// -------------------------
Vectors:
        b     _start                    // reset - _start
        ldr   pc,_undf                  // undefined - _undf
        ldr   pc,_swi                   // SWI - _swi
        ldr   pc,_pabt                  // program abort - _pabt
        ldr   pc,_dabt                  // data abort - _dabt
        nop                             // reserved
        ldr   pc,[pc,#-0xFF0]           // IRQ - read the VIC
        ldr   pc,_fiq                   // FIQ - _fiq

_undf:  .word __undf                    // undefined
_swi:   .word __swi                     // SWI
_pabt:  .word __pabt                    // program abort
_dabt:  .word __dabt                    // data abort
_irq:   .word __irq                     // IRQ
_fiq:   .word __fiq                     // FIQ

__undf: b     .                         // undefined
__swi:  b     .                         // SWI
__pabt: b     .                         // program abort
__dabt: b     .                         // data abort
__irq:  b     .                         // IRQ
__fiq:  b     .                         // FIQ

        .size _boot, . - _boot
        .endfunc

Lets look first at the reset/start vector:

b   _start

That instruction is an unconditional branch (a jump) to the the code labeled “_start” which I don’t see in your snippet. Basically it’ll be the assembly that initializes the stack and processor registers, maybe some memory areas then probably jumps to a C routine that performs the bulk of the initialization.

Next is the “undefined” vector that the ARM will go to when an invalid instruction is executed (if my memory is right):

ldr pc, _undf

That instruction loads the pc register (the ‘program counter’ or instruction pointer) with the address at the “_undf” symbol. If we look at the _undf variable, it contains the address represented by symbol __undf. So the ldr pc, _undf instruction loads pc with __undf‘s address – jumping to __undf:.

And at __undf we see:

__undf: b     .  

That’s just a branch to the same address – an infinite loop (the . symbol means ‘here’ or ‘this location’).

So for most of these vectors (which follow the same technique as the undefined vector), they’ll just jump to little infinite loops. You could replace the infinite loops at those labels with code that’s appropriate for the vector in question, though many projects don’t because those vectors firing would represent some sort of serious error.

Finally, the vector slot that’s most interesting is the IRQ vector:

ldr   pc,[pc,#-0xFF0]           // IRQ - read the VIC

This looks like the handler for an NXP device.

It loads the pc register with the value read from a memory location that’s relative to the pc register. Since on the ARM architecture the IRQ vector is always at address 0x00000018 (I’m going to ignore implementations that can map the vectors elsewhere or ARMs like the Cortex-M3 that use a different vector model) and because of the instruction pipeline’s effect on using the PC register value for addressing, the memory location that will be read by this instruction will be 0xFFFFF030, which is the address of the memory-mapped VICVectAddr register in the ‘Vectored Interrupt Controller` (VIC):

 'apparent'      Pipeline      offset in      effective
  PC value        effect       the opcode      address
-------------   ------------   -----------    ----------
  0x00000018  +  0x00000008  -  0x0000ff0  == 0xfffff030

This device register will contain the address of the interrupt handler for the interrupt that just occurred (of course the VIC needs to be properly initialized so it knows that address).

So when the ldr pc,[pc,#-0xFF0] instruction executes, it’ll load the pc register with the address of the interrupt handler routine for the appropriate device (basically, jumping to the right interrupt handler).

Originally posted 2013-11-09 22:51:02.