2014-02-27 58 views
0

目前我正在一个项目中,我必须将程序集AVR代码迁移到C代码。当然,我是亲自动手做的,因为这是最有效的方法。问题是我遇到了一个我无法弄清楚的问题。。包括在AVR汇编指令

我不知道哪个是我的程序执行的正确顺序。我认为这是主要的文件开始是这样的:

.INCLUDE "m8def.inc" ; NO SE QUE SIGNIFICA ESTO 
.INCLUDE "macro.asm" ; 
.INCLUDE "options.asm" 

.LISTMAC 
;*************************************************************************** 

.INCLUDE "define.asm"  ; port bits, constants 
.INCLUDE "ram.asm"  ; ram definitions 

;*************************************************************************** 
;*************************************************************************** 
;* 
;* Start of code 
;* 
;*************************************************************************** 
;*************************************************************************** 

.cseg  ;Indicates that the next segment refers to program memory; 
.org 0 ; The ORG directive is used to specify a location in program memory where the program following directive is to be placed. 

; Interrupt vectors 

rjmp RESET  ; Reset 
rjmp EXT_INT0 ; INT0 (not used) 
rjmp EXT_INT1 ; INT1 (not used) 
rjmp TIM2_COMP ; Timer2 compare (not used) 
rjmp TIM2_OVF ; Timer2 overflow (not used) 
rjmp TIM1_CAPT ; Timer1 capture (zero crossing input) 
rjmp TIM1_COMPA ; Timer1 compareA (ZX detector timing) 
rjmp TIM1_COMPB ; Timer1 compareB (not used) 
rjmp TIM1_OVF ; Timer1 overflow (not used) 
rjmp TIM0_OVF ; Timer0 overflow 
rjmp SPI_INT  ; SPI interrupt (not used) 
rjmp UART_RX  ; UART Rx complete 
rjmp UART_TX  ; UART UDR empty 
rjmp UART_TX  ; UART Tx complete (not used) 
rjmp ADC_INT  ; ADC interupt (not used) 
rjmp EERDY_INT ; EEPROM ready interrupt (not used) 
rjmp ANA_COMP ; Analog Comparator (not used) 
rjmp TWI  ; TWI (not used) 
rjmp SPM_RDY  ; SPM_RDY (not used) 

;--------------------------------------------------------------------------- 

.INCLUDE "int.asm"  ; interrupt service routines 

RESET: 

.INCLUDE "init.asm"  ; initialisation 

;*************************************************************************** 
;*************************************************************************** 
;* 
;* Main loop 
;* 
;*************************************************************************** 
;*************************************************************************** 

; .IF $ != ENDINIT 
; error "main.asm must follow init.asm" 
; .ENDIF 

sbi PORTD, PD_LED  ; 1 = LED on 
nop 
cbi PORTD, PD_LED 

; ldi uart_char, 'Z'  ; 0x5A for test only 
; rcall snd_echo 

; Main loop 

main_lp: 

羯羊的JMP指令时,或者不是我不明白......你能帮助我吗?谢谢!

+1

这看起来比ARM更像AVR组件。 – Michael

+0

['m8def.inc'](https://github.com/bitdump/BLHeli/blob/master/Atmel/m8def.inc)适用于AVR微处理器ATmega8。 –

+0

哦,谢谢。然后,执行的第一条指令是sbi PORTD,PD_LED ?? – Aldridge1991

回答

2

flash中的最低项必须包含跳转语句到中断服务例程。这被称为中断向量表。其原因是当触发该类型的中断时,处理器会自动进入这些位置。这是由硬件决定的,不能更改。

这些中断向量仅相距4个字节,因此中断服务程序本身没有空间,仅适用于单跳转指令。表中的标签也位于文件int.asm中,因此代码的结构在前端具有服务例程。这是一个选择,但他们不一定要在前面。

当器件开启时,位置0的指令运行,就像一个复位中断被触发一样。就你而言,这是跳转到RESET标签。

正如您所注意到的,主循环前面有一些代码位于文件init.asm中,它首先运行。这通常是代码,它将RAM设置为0,代表尚未初始化的全局和静态变量,还有一些代码将全局变量和静态变量的初始值从闪存复制到具有初始值的RAM的RAM。 (函数的局部变量位于堆栈中,函数中包含用于初始化它们的代码以及用于保存和恢复函数使用的寄存器中的值的代码。)

此初始化代码运行后,你的主循环运行。

我看不到你的特定初始化代码是什么。如果它是我所怀疑的,那么你就不必用C编写它。它是C运行库(crt0)的一部分,编译器会自动添加它。您也不必构造中断表。使用AVR宏包含你想要的,编译器将完成剩下的工作。

1

以上评论表明这些是interrupt vectors。当第n个中断触发时,第n个向量(跳转)被采用。

这些总是在地址0,这就是为什么你事先看到。

当微处理器复位时,它跳转到复位向量。在您的代码中,rjmp s到RESET标签,这正好在.INCLUDE "init.asm"之前。最有可能的是,该文件中的初始化代码首先运行,然后落入主循环代码(sbi指令)。看看这个init.asm文件。

+0

是的,你说的是对的,但是.include“init.asm”意味着这个文件内的代码在main_lp之前执行? – Aldridge1991

+0

.include接受指定的文件,基本上将其内容替换为.include指令。所以,是的,它在main_lp之前运行 –