微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > IAR下的汇编/单片机启动代码汇编

IAR下的汇编/单片机启动代码汇编

时间:11-25 来源:互联网 点击:

化(仅针对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

上一篇:MSP430汇编指令
下一篇:写MSP430片内flash

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top