微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > 混合使用C、C++和汇编语之:内联汇编和嵌入型汇编的使用

混合使用C、C++和汇编语之:内联汇编和嵌入型汇编的使用

时间:08-30 来源:3721RD 点击:

v6指令集中的指令。

12.1.3 内联汇编中使用SP、LR和PC寄存器的遗留问题

虽然目前的编译器不支持在内联汇编中使用SP、LR和PC寄存器,但在RVCT v1.2及其以前的编译器版本中是允许的。下面的例子显示了使用早期编译器版本,在内联汇编中使用LR寄存器的例子。

void func()

{

int var;

__asm

{

mov var, lr /* 得到func()函数的返回地址 */

}

}

如果使用RVCT v2.0编译器编译上面的代码,编译器将报告以下错误。

Error: #20: identifier "lr" is undefined

使用RVCT v2.0版本及其以后的编译器,要在C或C++代码中使用汇编访问SP、LR和PC寄存器可以使用下面几种方法。

① 使用嵌入式汇编代码。嵌入式汇编支持所有的ARM指令,同时允许在代码中访问SP、LR和PC寄存器。

② 在内联汇编中使用以下一些指令。

· __current_pc():访问PC寄存器。

· __current_sp():访问SP寄存器。

· __return_address():访问LR,返回地址寄存器。

下面给出了两个访问SP、LR和PC寄存器的典型实例程序。

① 使用编译器给定的指令。

void printReg()

{

unsigned int spReg, lrReg, pcReg;

__asm {

MOV spReg, __current_sp()

MOV pcReg, __current_pc()

MOV lrReg, __return_address()

}

printf("SP = 0x%X\n",spReg);

printf("PC = 0x%X\n",pcReg);

printf("LR = 0x%X\n",lrReg);

}

② 使用嵌入式汇编。

__asm void func()

{

MOV r0, lr

...

BX lr

}

使用嵌入式汇编可以使用调试器捕获程序的返回地址。

12.1.4 内联汇编代码与嵌入式汇编代码之间的差异

本节总结了内联汇编和嵌入式汇编在编译方法上存在的差异:

· 内联汇编代码使用高级处理器抽象,并在代码生成过程中与C和C++代码集成。因此,编译程序将C和C++代码与汇编代码一起进行优化。

· 与内联汇编代码不同,嵌入式汇编代码从C和C++代码中分离出来单独进行汇编,产生与C和C++源代码编译对象相结合的编译对象。

· 可通过编译程序来内联内联汇编代码,但无论是显式还是隐式,都无法内联嵌入式汇编代码。

表12.1总结了内联汇编程序与嵌入式汇编程序之间的主要差异。

表12.1 内联汇编程序与嵌入式汇编程序之间的主要差异

功 能

嵌入式汇编程序

内联汇编程序

指令集

ARM和Thumb

仅支持ARM

ARM汇编指令伪操作

支持

不支持

ARMv6指令集

支持

仅支持媒体指令

C/C++表达式

只支持常数表达式

完全支持

汇编代码是否优化

无优化

完全优化

能否被内联(Inling)

不可能

有可能被内联

续表

功 能

嵌入式汇编程序

内联汇编程序

寄存器访问

使用指定的物理寄存器,还可以使用PC、LR和SP

使用虚拟寄存器。不能使用PC、LR和SP寄存器

是否自动产生返回指令

手工添加返回指令

指定产生(但不支持BX、BXJ和BLX指令)

是否支持BKPT指令

不直接支持

不支持

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

网站地图

Top