vectorinterruptavr

Interrupt vector addresses in AVR ATmega2560


I have a question concerning the addresses of the interrupt vectors in ATmega2560.

  1. According to the data sheet, the vectors are at the program addresse $0000, $0002, $0004, ..., $0070.

  2. After disassembling code of an ATmega2560 (on an Arduino Mega board) I noticed that the vector are at the addresses $0000, $0004, $0008, ..., $00E0.

I assume that (2) is correct. According to the AVR Instruction set manual a JMP instruction has a 4 Byte opcode which fits this assumption (and the assembler uses the JMP instruction to jump to the ISR).

But why does the data sheet then tell something different? Or is my understanding maybe totally wrong?

Thanks a lot for all answers and kind regards!


Solution

  • The "difference" is since in the AVR manuals, addresses in program memory are usually specified as word addresses (since the program memory is addressed in words, at least as far as code fetching is concerned).

    The list files generated with objdump show byte addresses for code locations. The only case where word addresses are used is when the address of a code location is taken, like for example in:

    int (*pmain)(void);
    
    int main (void)
    {
        pmain = main;
        return 0;
    }
    
    $ avr-gcc -mmcu=atmega2560 -Os -o main.elf main.c
    $ avr-objdump -h -d -S -r main.elf
    
    Disassembly of section .text:
    
    00000000 <__vectors>:
       0:   0c 94 74 00     jmp 0xe8    ; 0xe8 <__init>
       4:   0c 94 88 00     jmp 0x110   ; 0x110 <__bad_interrupt>
    ...
    000000e8 <__init>:
      e8:   11 24           eor r1, r1
      ea:   1f be           out 0x3f, r1
      ec:   cf ef           ldi r28, 0xFF
    ...
    00000114 <main>:
     114:   8a e8           ldi r24, 0x8A   ; 138
     116:   90 e0           ldi r25, 0x00   ; 0
     118:   90 93 01 02     sts 0x0201, r25 ; <pmain+0x1>
     11c:   80 93 00 02     sts 0x0200, r24 ; <pmain>
    ...
    

    So the code jumps from the reset vector to 0xe8, which is a byte address (but encoded in JMP as a word address).

    When main takes its own address, it loads the word address 0x8A to R25:24, which as a byte address is 2 * 0x8A = 0x114.