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

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

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

my_operand ();

}

由编译器编译出的汇编代码如下所示(其中只列出了内联汇编的一段代码)。

my_operand:

0000807C E3A01000 MOV r1,#0

>>> OPERANDS\#12 mov j,#1

00008080 E3A00001 MOV r0,#1

00008084 E0812000 ADD r2,r1,r0

>>> OPERANDS\#13 add total,j,i+j

00008088 E0803002 ADD r3,r0,r2

>>> OPERANDS\#15 }

0000808C E12FFF1E BX r14

>>> OPERANDS\#19 {

从编译的代码可以看出,编译器将"add total,j,i+j"分为两步来完成,用户在编写自己的内联汇编应用程序时要特别注意这一点。

包含多个表达式操作数的指令,没有指定表达式操作数求值的顺序。

将C或C++表达式用作内联汇编程序操作数,如果表达式的值不能满足 ARM指令中所要求的指令操作数约束条件,一条指令将被扩展为多条指令。

如果用作操作数的表达式创建需要析构的临时函数,析构将发生在执行内联汇编指令之后,这与C++析构临时函数的规则相类似。

简单表达式操作数包含以下几种类型。

· 变量值

· 变量地址

· 指针变量的反引用(the dereferencing of a point varable)

· 伪操作指定的程序常量

非简单表达式操作数包含以下几种类型。

· 隐式函数调用,如除法,或显式函数调用

· C++临时函数的构造

· 算术或逻辑操作

(3)寄存器列表

寄存器列表最多可包含 16 个操作数。这些操作数可以是虚拟寄存器或表达式操作数。在寄存器列表中指定虚拟寄存器和表达式操作数的顺序非常重要。寄存器列表中操作数的读写顺序是从左到右。第一个操作数使用最低地址,随后的操作数的地址依次在前一地址基础上增加 4。这一点与LDM 或 STM 指令的普通操作(编号最低的物理寄存器总是存入最低的存储器地址)是不同的。之所以存在这种区别是因为在内联汇编中使用的寄存器被编译器虚拟化了。

同一个表达式操作数或虚拟寄存器可以在寄存器列表中出现多次,重复使用。

如果表达式操作数或虚拟寄存器被指定为指令中的基址寄存器,表达式或虚拟寄存器的值按照ARM指令寻址方式进行更新。更新将覆盖原表达式或虚拟寄存器的值。

(4)中间操作数(Intermediate operands)

在内联汇编指令中,可能将C或C++整型常量表达式用作立即数处理。用于指定直接移位的常量表达式的值必须在ARM指令规定的移位操作数的范围内;用于为存储器或协处理器数据传送指令指定直接偏移量的常量表达式,必须符合ARM体系结构中的内存对齐标准。

8.函数调用和分支跳转

利用内联汇编程序的BL和SWI指令可在常规指令字段后指定3个可选列表。这些指令格式有以下几种。

SWI{cond} swi_num , { input_param_list }, { output_value_list }, { corrupt_reg_list }

BL{cond} function, { input_param_list }, { output_value_list }, { corrupt_reg_list }

其中,swi_num为SWI调用的中断号;function为被调用函数名;{input_param_list}为输入参数列表;{output_value_list}为输出参数列表;{corrupt_reg_list}为被破坏寄存器列表。

注意

内联汇编程序不支持BX、BLX和BXJ指令。不能在任何输入、输出或"被破坏的寄存器列表(corrupted register list)"中指定lr、sp或pc寄存器;任何SWI指令或函数调用不能更改sp寄存器。

下面分别详细介绍语法格式中各参数的使用。

(1)未指定任何列表

如果在SWI和BL指令后没指定任何列表,则有下面规则。

· r0~r3用作输入参数;

· r0 用于输出值;

· r12和r14的值将会被修改。

(2)输入参数列表

指令中的输入参数列表{ input_param_list }列出了传递给被调用函数function和SWI的参数。被传递的参数可以是表达式、变量或包含表达式或变量的物理寄存器。

内联汇编编译器在编译时增加一小段编译程序负责在函数和SWI调用前

将传递的参数载入特定的物理寄存器中。为确保与现有内联汇编代码的向后兼容性,程序中指定物理寄存器名称而并不对其赋值,使相同名称虚拟寄存器中的值出现在物理寄存器中。

例如,指令BL foo {r0=expression1, r1=expression2, r2}生成以下伪代码:

MOV (physical) r0, expression1

MOV (physical) r1, expression2

MOV (physical) r2, (virtual) r2

BL foo

(3)输出参数列表

输出参数列表{ output_value_list }列出了用来存放功能函数和SWI调用返回值的寄存器或表

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

网站地图

Top