混合使用C、C++和汇编语之:内联汇编和嵌入型汇编的使用
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指令 | 不直接支持 | 不支持 |
C C++ 汇编语言 ARM 内联汇编 嵌入型汇编 相关文章:
- RedHatLinux新手入门教程(5)(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- VXWORKS内核分析(11-11)
- 嵌入式开发工具简介(11-09)
- Linux2.4内核为我们带来了什么?(11-12)
- RedHatLinux新手入门教程(11-12)