Yahoo Groups archive

Lpc2000

Index last updated: 2026-04-28 23:31 UTC

Message

Re: Long unconditional brach - assembler

2005-07-22 by Karl Olsen

--- In lpc2000@yahoogroups.com, "xjag74" <detlef.weidner@w...> wrote:

> is there a way to realize a long unconditional branch in assembler?
> 
> What I try to do is to jump from the interrupt vector table -
> located at the begin of the external memory - to the FIQ service
> routine, located in the internal RAM, cause I want to profit from
> the execution performance.

If your FIQ handler can fit in 9 instructions, you can relocate the 
interrupt vectors to internal RAM, and have your handler in the 36 
bytes at 001Ch-003Fh.  Your handler can also use the word at 0000h
(the reset vector) and 0014h (the "reserved" vector"), and possibly 
other vectors you don't use.  In case of a hardware reset, the MEMMAP 
register is reset, so the real reset vector is read from flash or 
external memory as normal.  This is the fastest as there are no jumps.

Remember that R8-R14 are private to the FIQ handler and can in the
main program be initialized with useful constants and variables 
(except R14), so a FIQ handler can often be quite small.

To jump from 001Ch to internal RAM, you can:

  MOV PC, #0x40000000

and end up at 0x40000000.  You can also do this:

  ADD PC, PC, #0x40000000

If this instruction is placed at 001Ch, you will end up at 0x40000024 
because PC is always 8 ahead of the current instruction.  Immediate 
constants are limited to 8 bit, rotated an even number of bits, so 
0x40000000 is a valid immediate value, and 0x40100000 is not.  This
is fast (3 clocks) and uses no other registers.

Placing your handler code at a specific address in internal RAM 
requires some linker script trickery if you use gcc.

To jump to an arbitrary address, you can

  MOV PC, R8

where R8 is somehow initialized to the destination address.  This is 
useful if you can initialize R8 in the main program, and leave it at 
that.  It is also fast (3 clocks) but uses a register.

If you cannot reserve one of the banked registers for this, you need 
something like this:

  LDR PC, [PC, #-4]
  .WORD FIQ_Handler

This loads PC with the address in the following word.  This is
slowest (5 clocks) but uses no registers.

In any case, you save some clocks by relocating the interrupt vectors 
to RAM.

Karl Olsen

Attachments

Move to quarantaine

This moves the raw source file on disk only. The archive index is not changed automatically, so you still need to run a manual refresh afterward.