IAR下的汇编/单片机启动代码汇编
化(仅针对GNU)。
8、跳转到C语言函数执行。
本文只是在探讨第一个步骤(定义中断和异常向量)。因为这个将会在之后我们要讲到的在uC/OS-II中进行中断函数的编写有关系,其他步骤,如果大家有兴趣,可以到网上去查阅相关资料。
下面代码就是我在MDK中,拷贝出来的一段初始化异常向量的代码了,详细代码如下:
AREA
RESET, CODE, READONLY
ARM
Vectors
LDRPC, Reset_Addr
LDRPC, Undef_Addr
LDRPC, SWI_Addr
LDRPC, PAbt_Addr
LDRPC, DAbt_Addr
NOP
;LDRPC, IRQ_Addr
LDRPC, [PC, #-0x0FF0]
LDRPC, FIQ_Addr
Reset_Addr DCD Reset_Handler
Undef_Addr DCD Undef_Handler
SWI_Addr DCD SWI_Handler
PAbt_Addr DCD PAbt_Handler
DAbt_Addr DCD DAbt_Handler
DCD 0
IRQ_Addr DCD IRQ_Handler
FIQ_Addr DCD FIQ_Handler
Undef_Handler B Undef_Handler
SWI_Handler B SWI_Handler
PAbt_Handler B PAbt_Handler
DAbt_Handler B DAbt_Handler
IRQ_Handler B IRQ_Handler
FIQ_Handler B FIQ_Handler
下面就进行一步一步代码分析:
1、
AREA
RESET, CODE, READONLY
ARM
这两段话表达的意思是:在代码段中定义一个段名为RESET的只读段,该代码段中的代码都在ARM指令集下进行。
2、Vectors
LDR PC, Reset_Addr
LDR PC, Undef_Addr
LDR PC, SWI_Addr
LDR PC, PAbt_Addr
LDR PC, DAbt_Addr
NOP
;LDR PC, IRQ_Addr
LDR PC, [PC, #-0x0FF0]
LDR PC, FIQ_Addr
上面的代码是ARM内核定义的异常像量表
异常类型
异常向量地址
该地址中的内容
复位
0x00000000(或0xFFFF0000)
LDR PC, Reset_Addr
未定义异常
0x00000004(或0xFFFF0004)
LDR PC, Undef_Addr
软件中断
0x00000008(或0xFFFF0008)
LDR PC, SWI_Addr
指令预取异常
0x0000000C(或0xFFFF000C)
LDR PC, PAbt_Addr
数据预取异常
0x00000010(或0xFFFF0010)
LDR PC, DAbt_Addr
预留
0x00000014(或0xFFFF0014)
NOP
IRQ中断
0x00000018(或0xFFFF0018)
LDR PC, [PC, #-0x0FF0]
FIQ中断
0x0000001C(或0xFFFF001C)
LDR PC, FIQ_Addr
大家注意一下,在中断向量地址中必须保存一条ARM指令集。在对应的异常向量地址中将跳转到对应的异常处理程序。
当然大家在这里也可以使用B指令,但是大家要注意一下,使用LDR指令可以实现±4GB地址空间实现。但是使用B执行跳转的话,就只能在±32M地址空间。所以建议大家使用LDR指令实现跳转。
可能大家看到了在IRQ中断向量地址中装载的是LDR PC, [PC, #-0x0FF0]指令,这里要和大家解释一下这条语句,在和大家解释这条语句时,希望大家去看看LPC2103的datasheet。
当处理器开始执行LDR PC, [PC, #-0x0FF0]
指令,PC寄存器的值就已经变成PC+8 = 0x20(这个不清楚的朋友必须去查询一下《ARM+Architecture+Reference+Manual(2nd+Edition)》中的Prefetch and self-modifying code),
Result = 0x20 – 0xff0 = 0xFFFFF030(实在不知道怎么算的就用电脑自带的计算器算算);
在查询LPC2103数据手册后,发现该地址对应的寄存器为VICVectAddr。
在这条语句执行完毕后,处理器就会跳转到导致产生IRQ中断,并跳转到VICVectAddr寄存器所指向的IRQ异常处理函数中进行操作。
实际运用中,我们可以更改一下IRQ异常向量地址的语句,让大家更加好看。更改如下:
LDR PC, [PC, #0xFFFFF020]
这条语句和刚才的MDK自带的语句实现的效果是一样的!
实例
软件实现中断处理过程
实验芯片:LPC2103
开发环境:MDK3.50
实现功能:在不使用__irq关键词时,如果编写中断服务程序。
知识要点:
1、在MDK开发环境下,对于LPC2000系列处理器,MDK默认的启动模式位系统模式。
2、在不使用__irq关键字声明时,只将中断处理函数当成普通函数进行处理,而不会在进入中断时对通用寄存器的内容进行保存,也不会再退出中断时对通用寄存器的内容进行恢复,因此这部分功能是必须手动添加的。
下面进行代码讲述,下面就是当进入IRQ中断处理函数时的处理程序,代码全部用汇编语句完成详细代码如下:
EXPORT IRQ_Uart0
IMPORT DuleUart0
REQUIRE8
PRESERVE8
AREA CODE, CODE, READONLY
CODE32
IRQ_Uart0
STMFD SP!,{R0-R12,LR}
;保存当前处理器的所有寄存器
MRS R0,SPSR
;保存当前处理器的SPSR
STMFD SP!,{R0}
MRS R0,CPSR ;保存当前处理器的CPSR
STMFD SP!,{R0}
MOV R12, SP ;保存当前的SP寄存器
MRS R0,CPSR ;重新打开FIQ或IRQ中断
BIC R0,R0,#0xC0
MSR CPSR_cxsf,R0
BL DuleUart0 ;执行串口0的实际处理程序
MOV SP,R12 ;恢复SP寄存器的值
LDMFD SP!,{R0} ;恢复中断时的CPSR寄存器值
MSR CPSR_cxsf,R0
LDMFD SP!,{R0};恢复中断前的SPSR寄存器状态
MS
IAR汇编单片机启动代 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)