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

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

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

1、

IAR汇编指令SFB和SFE

SFB Segment begin 段开始

语法格式

SFB(segment [{+|-} offset])

参数

segment: 可重定位段的段名, 必须在SFB使用前已定义

offset : 从开始地址的偏移, 是一个可选参数, 当偏移量省略时, 可以不添加小括号

描述

SFB 右边可以接受一个操作数, 而且这个操作数必须是一个可重位段的段名.

这个操作符计算段的首字节地址. 这个操作发生在连接时.

NAME demo

RSEG CODE

start: DC16 SFB(CODE)

即使上面的代码和多个其他的模块进行连接, start标号处仍被置为段的首字节地址

语法格式

SFE (segment [{+|-} offset])

参数

segment: 可重定位段的段名, 必须在SFB使用前已定义

offset : 从开始地址的偏移, 是一个可选参数, 当偏移量省略时, 可以不添加小括号

描述

SFE在其右边接收一个操作数. 操作数必须是一个可重定位段的段名. SFE操作符将段起始地址和段大小相加. 这个操作在连接时发生.

SFE accepts a single operand to its right. The operand must be the name of a relocatable segment. The operator evaluates to the segment start address plus the segment size. This evaluation takes place at linking time.

NAME demo

RSEG CODE

end: DC16 SFE(CODE)

即使当上面的代码被和多个模块想连接时, end标号仍然会被置为段最后一个字节的地址. Even if the above code is linked with many other modules, end will still be set to the address of the last byte of the segment.

段MY_SEGMENT的大小可以通过以下方式计算而得:

SFE(MY_SEGMENT)-SFB(MY_SEGMENT)

--------------------------------------------------------------------------------

arm中的几种跳转

arm汇编的跳转指令无非是b和ldr。但是如果没有足够理解,别人灵活的用一下你就犯晕了。

首先我们要知道两者的两个本质区别:

1、b是位置无关的,ldr不是位置无关的。

2、b的范围只能是+—32MB,而ldr是4GB。

在arm的启动汇编的中断向量表是必然用跳转指令的,但是就是这里也有很多实现形式:

方式1:

B InitReset ; 0x00 Reset handler

undefvec:

B undefvec ; 0x04 Undefined Instruction

swivec:

B swivec ; 0x08 Software Interrupt

pabtvec:

B pabtvec ; 0x0C Prefetch Abort

dabtvec:

B dabtvec ; 0x10 Data Abort

rsvdvec:

B rsvdvec ; 0x14 reserved

irqvec:

B IRQ_Handler_Entry ; 0x18 IRQ

这个我很容易理解,实现的标号油InitReset和IRQ_Handler_Entry,其他没有实现的在原地跳转。

方式二:

LDR pc, =resetHandler ; Reset

LDR pc, Undefined_Addr ; Undefined instructions

LDR pc, SWI_Addr ; Software interrupt (SWI/SYS)

LDR pc, Prefetch_Addr ; Prefetch abort

LDR pc, Abort_Addr ; Data abort

B . ; RESERVED

LDR pc, =irqHandler ; IRQ

LDR pc, FIQ_Addr ; FIQ

LDR PC,[PC,#0x18]

Undefined_Addr: DCD Undefined_Handler

SWI_Addr: DCD SWI_Handler

Prefetch_Addr: DCD Prefetch_Handler

Abort_Addr: DCD Abort_Handler

FIQ_Addr: DCD FIQ_Handler

我们注意到两种ldr

一种LDR PC,=label,这时把LDR当做伪指令,他要被翻译成:

LDR PC,[PC,offset_to_label2]

label2:DCD resetHandler

这种label是在程序中标记的了,如resetHandler和irqHandler

还有一种LDR PC,label,这时直接把label地址内存内容copy到PC中

这种label都是 label:DCD label2 ,这些label2可以在任何地方实现

我们来理解b和ldr两者的不同

1,b是位置无关,因为他的跳转都是相对PC来的,而ldr不是位置无关的,因为他的跳转是根据DCD里面的值,这个值是连接的时候确定的,他是跟连接地址有关的

2,b的范围只能是32M,是因为指令里面给偏移的空间只有24bit,而ldr是一个32bit的DCD,所以他是32bit的

注意:像上面方式二

LDR pc, =resetHandler ; Reset

resetHandler:

....

....

如果运行地址是0,那么LDR pc, =resetHandler还在以基址为0的空间运行

但是执行完了,假设装载地址是0x3000000,所以resetHandler的基址不是0,而是0x30000000

所以resetHandler标号以后的指令应该存在以0x3000000为基址的空间,pc跳过去了

这种技巧在at91的remap模式经常用到

-----------------------------------------------

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

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

网站地图

Top