CONTENTS
备注:
1 本部分文档摘录自ARM网站【 http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0348bc/CJAHICFI.html 】,版权归属于ARM。
2 作者只摘录了部分内容,全面详细的内容清参考ARM网址。
7.2 嵌入式汇编器
利用 ARM 编译器可将汇编代码外联包括到一个或多个 C 或 C++ 函数定义中。嵌入式汇编器支持对目标处理器进行非受限底层访问,使您可以使用 C 和 C++ 预处理程序指令,还可以方便地对结构成员偏移量进行访问。
有关为 ARM 处理器编写汇编程序的详细信息,请参阅《汇编器指南》。
7.2.1. 嵌入式汇编器语法
嵌入式汇编程序定义由 __asm(C 和 C++)或 asm (C++) 函数限定符标记,可用于:
成员函数
非成员函数
模板函数
模板类成员函数。
用 __asm 或 asm 声明的函数可以有参数并返回一个类型。它们从 C 和 C++ 中调用的方式与普通 C 和 C++ 函数的调用方式相同。嵌入式汇编程序的语法是:
__asm return-type function-name(parameter-list)
{
// ARM/Thumb/Thumb-2 assembler code
instruction[;instruction]
…
instruction
}
如命令行指定的那样,嵌入式汇编器(ARM 或 Thumb)的初始状态由编译器的初始状态确定。这意味着:
如果编译器在 ARM 状态下启动,则嵌入式汇编器将使用 –arm
如果编译器在 Thumb 状态下启动,则嵌入式汇编器将使用 –thumb。
每个函数的起始嵌入式汇编器状态与 #pragma arm 和 #pragma thumb 编译指示修改的编译器调用时设置相同。
可以在嵌入式汇编器中使用显式 ARM、THUMB 或 CODE16 指令,更改函数内的嵌入式汇编器状态。__asm 函数内的此类指令不影响随后的 __asm 函数的 ARM 或 Thumb 状态。
如果要编译支持 Thumb-2 的处理器,则可以在 Thumb 状态下使用 Thumb-2 指令。
Note
自变量名允许用在参数列表中,但不能用在嵌入式汇编程序体内。例如,以下函数在函数体内使用整数 i,但在汇编中无效:
__asm int f(int i)
{
ADD i, i, #1 // error
}
例如,可以使用 r0 代替 i。
有关 C 和 C++ 源代码中的嵌入式汇编语言的详细信息,请参阅《开发指南》 中有关混合使用 C、C++ 和汇编语言的章节。
嵌入式汇编器示例
Example 7.1 显示了用作嵌入式汇编器例程的字符串复制例程。
Example 7.1. 用嵌入式汇编器进行字符串复制
#include <stdio.h>
__asm void my_strcpy(const char *src, char *dst)
{
loop
LDRB r2, [r0], #1
STRB r2, [r1], #1
CMP r2, #0
BNE loop
BX lr
}
int main(void)
{
const char *a = “Hello world!”;
char b[20];
my_strcpy (a, b);
printf(“Original string: ‘%s’\n”, a);
printf(“Copied string: ‘%s’\n”, b);
return 0;
}
7.2.5. __cpp 关键字
使用 __cpp 关键字可以在汇编代码中访问 C 或 C++ 编译时常数表达式,包括含有外部链接的数据或函数的地址。__cpp 内的表达式必须是适合用作 C++ 静态初始化的常数表达式。请参阅 ISO/IEC 14882:2003 中的 3.6.2 非局部对象的初始化 (Initialization of non-local objects) 和 5.19 常量表达式 (Constant expressions)。
Example 7.3 演示一个用于替代 __cpp(expr) 的常数:
Example 7.3. __cpp(expr)
LDR r0, =__cpp(&some_variable)
LDR r1, =__cpp(some_function)
BL __cpp(some_function)
MOV r0, #__cpp(some_constant_expr)
发表评论