再上一篇:第18章
上一篇:18.2 系统的个性
主页
下一篇:18.4 C 源程序
再下一篇:18.5 预编译的目标文件
文章列表

18.3 汇编源程序

《Cortex-M3 权威指南》,嵌入式处理器开发教程。

对汇编源程序的移植取决于使用的是 ARM状态还是 Thumb状态。

18.3.1 Thumb状态

如果使用的是 thumb汇编源文件,则是幸运的,在大多数情况下代码可以直接拿来用。只有个 别的 thumb指令在 CM3中不可用:
 任何试图转入 ARM状态的指令(典型就是 BLX)
 不再支持 SWI,而是要使用 SVC,而且用法上也有区别 最后,一定要只使用向下生长的满栈,CM3的 push 和 pop 就是使用这种模型的——总有程序
喜欢玩另类,结果不但移植工作量加重了,也无法使用 C 语言了。因此可别在这里秀“叛逆精神” 啊,否则会自找苦吃的,而且向下生长的满栈本来就是更合理的。

18.3.2 ARM状态

如果不幸在汇编源文件中使用了 ARM状态,也不要慌,仔细核对下列情况:
 向量表:在 ARM7中,向量表从 0地址开始,并且由一系列的跳转指令组成。在 CM3中, 跳转表给出了 MSP 的初值以及复位向量地址,接下来的则是各异常服务例程的入口地址。 因此这些区别是本质上的不同,向量表必须重写。
 寄存器初始化:在 ARM7 中,经常需要把每个模式下的寄存器分别初始化。比如,每个模 式(除系统模式外)都有自己的 SP、LR和 SPSR。CM3去掉了这些繁文缛节,而且也不再 需要把处理器的模式换来换去。
 模式切换与状态切换:在 CM3不再保留 ARM7中的那些操作模式,也没有 Thumb状态,因 此相关的代码都可以移除。
 中断的使能与除能:在 ARM7 中,中断的使能与除能是通过对 CPSR.I 来控制的。在 CM3 中则改用 PRIMASK 或 FAULTMASK。更进一步地,CM3 中没有 FIQ 的概念,因此也没有 F 位。
 协处理器访问:CM3 不支持协处理器,因此相关的代码无法移植。但是可以通过软件模拟 的办法来缓解
 中断服务例程和中断返回:在 ARM7中,中断服务例程的首条指令在向量表中。这条指令, 除了 FIQ服务例程的外,都必须是一种无条件跳转指令,而 CM3中则是直接在向量表中给 出ISR的入口地址。中断返回时,ARM7是通过带S后缀的指令手工地调整PC的值来实现; 而 CM3 则把需要返回的地址压入堆栈中,并且通过把某个 EXC_RETURN 写入 PC 来触发中 断返回序列。因此,在 CM3中,不得使用诸如 MOVS或 SUBS之类的指令来启动中断返回。 由于这些原因,中断服务例程和中断返回的代码需要加以改动。
 当需要启用中断嵌套时,ARM7 的作法通常是先进入系统模式再重新使能 IRQ,在 CM3 中 则没有这些操作。
 FIQ服务例程:因为在 ARM7中,FIQ有专用的 R8-R12;而 CM3则自动保存了 R0-R3,R12。 所以如果必须要移植 FIQ 服务例程,则需要手工保存 R8-R11。或者把本来对 R8-R11 的 使用,改为以 R0-R3的使用。
 软件中断(SWI)服务例程:SWI 由 SVC 取代。不过,定位软件中断指令并萃取系统调用号 的作法不同。在 CM3中,通过压入栈的返回地址来计算出 SVC指令的地址;而在 ARM7中, 则是通过 LR来计算。
 交换指令(SWP):在 CM3中没有交换指令。如果以前使用 SWP来实现信号量,则要改为使 用互斥访问来实现,因此需要改动信号量相关的代码。如果以前使用 SWP只是为了纯粹地 传送数据,则需要使用若干存储器访问指令来实现。
 对 CPSR和 SPSR的访问:ARM7中的 CPSR在 CM3变成了 xPSR,而 SPSR则被去掉了。对 于访问标志的应用程序代码,可以改为对 APSR 的访问。如果异常服务例程想要访问异常 发生之前的 xPSR,则要读取压入堆栈中的值——这取代了 ARM7中 SPSR的功能,因此 CM3 中不再需要 SPSR。
 条件执行:在 ARM7中,大量指令都可以条件执行;而 Thumb-2的指令则几乎都不能条件 执行。在移植这些代码到 CM3中时,对于短小的条件执行段,可以用 IF-THEN指令封装; 而比较大的则需要使用跳转指令来改建。当使用 IT 指令时要注意一些小问题。主要就是 会增加代码量,有可能使得某些加载/存储指令超出最大可操作的地址范围。
 使用 PC计算当前代码的地址:在 ARM7中,读取的 PC值“读 PC指令的地址+8”。这是由
ARM7的三级流水线造成的——当读取 PC的指令处于执行阶段时,PC已经自增了两次。同 样的事情也发生在 CM3中,但是在代码移植到 CM3后,因为这些代码将在 Thumb下执行, 所以 PC被加的值变成 4。
 对 R13的使用:R13总是 32位的。但是在 CM3中,末 2位被强制为 0。因此,如果偶尔 遇到使用 R13 作为基址的场合(强烈反对使用),必须更改代码,因为末 2 位的信息已经 丢失了。