AVR 汇编中断向量 Table

AVR Assembly Interrupt Vectors Table

我正在尝试 assemble(使用 avr-gcc)ATMega328p 中的一个程序,该程序具有外部中断(准确地说是在 INT0 引脚中)。

但是我在编译的时候遇到了很大的麻烦。 disassembled 代码没有加载中断向量 table。

汇编代码(用于AVR):

.equ F_CPU, 16000000
.text
.global main
    .org 0x0000         ; changes interrupt vector table to INT0 ISR
    rjmp main           ; goto main     ---> ISR for main
    rjmp INT0_vect      ; goto EXT_INT0 ---> ISR for INT0 pin
INT0_vect:              ; IRQ0 Handler --> ISR code for INT0 pin
    ldi r16,0x20
    out PORTB,r16       ; turns led on
    reti                ; return from interrupt
.include "m328pdef.inc" ; main addresses in atmega328p
.include "wait.asm"     ; wait 1 second function delaration
main:                   ; interrupt setup (runs only once by reset)
    ldi r16,(1<<ISC01)|(1<<ISC00)   ; interrupts on rising edge of INT0
    sts EICRA,r16       ; setting the bits
    ldi r16,(1<<INT0)   ; Setting the interrupt request 0 to be enabled
    sts EIMSK,r16       ; Setting the interrupt request 0 to be enabled done
    sei                 ; enable global interrupts
loop:                   ; loop, main function repeats ...
    ldi r16,0x00
    out PORTB,r16       ; turns led off
    call wait           ; wait 1 second function
    rjmp loop

反汇编二进制文件时,我得到:

00000000 <__vectors>:
    0:  0c 94 34 00     jmp 0x68    ; 0x68 <__ctors_end>      ; RESET ISR SO FAR SO GOOD
    4:  0c 94 3e 00     jmp 0x7c    ; 0x7c <__bad_interrupt>  ; INT0 ISR NOT POINTING TO 0x84 ADDRESS
    8:  0c 94 3e 00     jmp 0x7c    ; 0x7c <__bad_interrupt>
    c:  0c 94 3e 00     jmp 0x7c    ; 0x7c <__bad_interrupt>
    (...)

00000068 <__ctors_end>:
    68: 11 24           eor r1, r1
    (...)
    74: 0e 94 63 00     call    0xc6    ; 0xc6 <main>
    78: 0c 94 6f 00     jmp 0xde    ; 0xde <_exit>

0000007c <__bad_interrupt>:
    7c: 0c 94 00 00     jmp 0   ; 0x0 <__vectors>
    80: 22 c0           rjmp    .+68        ; 0xc6 <main>
    82: 00 c0           rjmp    .+0         ; 0x84 <INT0_vect>

00000084 <INT0_vect>:
    84: 00 e2           ldi r16, 0x20   ; 32
    86: 05 b9           out 0x05, r16   ; 5
    88: 18 95           reti

0000008a <wait>:
    (...)

000000de <_exit>:
    de: f8 94           cli

000000e0 <__stop_program>:
    e0: ff cf           rjmp    .-2         ; 0xe0 <__stop_program>

预期反汇编:

00000000 <__vectors>:
    0:  0c 94 34 00     jmp 0x68    ; 0x68 <__ctors_end>      ; RESET ISR SO FAR SO GOOD
    4:  0c 94 XX 00     jmp 0x84    ; 0x84 <INT0_vect>        ; <--- Jump to INT0 ISR
    8:  0c 94 3e 00     jmp 0x7c    ; 0x7c <__bad_interrupt>
    c:  0c 94 3e 00     jmp 0x7c    ; 0x7c <__bad_interrupt>
    (...)

00000068 <__ctors_end>:
    68: 11 24           eor r1, r1
    (...)
    74: 0e 94 63 00     call    0xc6    ; 0xc6 <main>
    78: 0c 94 6f 00     jmp 0xde    ; 0xde <_exit>

(...)

00000084 <INT0_vect>:
    84: 00 e2           ldi r16, 0x20   ; 32
    86: 05 b9           out 0x05, r16   ; 5
    88: 18 95           reti

(...)

Makefile(编译命令)为:

CC = avr-gcc
OBJ = avr-objcopy
DUMP = avr-objdump
SIZE = avr-size
MCU = -mmcu=atmega328
FLAGS = -c -x assembler-with-cpp
all:main.hex
main.hex:main.elf
    $(OBJ) -j .text -j .data -O ihex main.elf main.hex
main.elf:main.o
    $(CC) $(MCU) -o main.elf main.o
main.o:main.asm
    $(CC) $(MCU) -x assembler-with-cpp  -o main.o main.asm
clean:
    rm *.o *.elf *.hex main.txt
size:
    $(SIZE) -C --mcu=atmega328p main.elf
dump:
    $(DUMP) -d main.elf > main.txt
dump-all:
    $(DUMP) -j .data -j .text -D main.elf > main.txt

有什么我遗漏的吗?

我使用 avr-gcc -mmcu=atmega328 -nostdlib -x assembler-with-cpp -o main.elf main.asm 而不是使用 avr-gcc 来 .asm->.o 然后 .o->.elf.

感谢Jester的支持!