×
嵌入式开发 > 详情

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

发布时间:2020-07-10 发布时间:
|

12.1内联汇编嵌入型汇编的使用

内联汇编嵌入型汇编是包含在C/C++编译器中的汇编器。使用它可以在C/C++程序中实现C/C++语言不能完成的一些工作。例如,在下面几种情况中必须使用内联汇编嵌入型汇编

·程序中使用饱和算术运算(Saturatingarithmetic),如SSAT16和USAT16指令。

·程序中需要对协处理器进行操作。

·在C或C++程序中完成对程序状态寄存器的操作。

使用内联汇编编写的程序代码效率也比较高。

12.1.1内联汇编

1.内联汇编语法

内联汇编使用“_asm”(C++)和“asm”(C和C++)关键字声明,语法格式如下所示。

·__asm(instruction[;instruction]); //必须为单条指令

__asm{instruction[;instruction]}

·__asm{

...

instruction

...

}

·asm(instruction[;instruction]); //必须为单条指令

asm{instruction[;instruction]}

·asm{

...

instruction

...

}

内联汇编支持大部分的ARM指令,但不支持带状态转移的跳转指令,如BX和BLX指令,详见ARM相关文档。

由于内联汇编嵌入在C或C++程序中,所有在用法上有其自身的一些特点。

①如果同一行中包含多条指令,则用分号隔开。

②如果一条指令不能在一行中完成,使用反斜杠“/”将其连接。

③内联汇编中的注释语句可以使用C或C++风格的。

汇编语言中使用逗号“,”作为指令操作数的分隔符,所以如果在C语言中使用逗号必须用圆括号括起来。如,__asm{ADDx,y,(f(),z)}。

⑤内联汇编语言中的寄存器名被编译器视为C或C++语言中的变量,所以内联汇编中出现的寄存器名不一定和同名的物理寄存器相对应。这些寄存器名在使用前必须声明,否则编译器将提示警告信息。

⑥内联汇编中的寄存器(除程序状态寄存器CPSR和SPSR外)在读取前必须先赋值,否则编译器将产生错误信息。下面的例子显示了内联汇编和真正汇编的区别。

错误的内联汇编函数如下所示。

intf(intx)

{

__asm

{

STMFDsp!,{r0} //保存r0不合法,因为在读之前没有对寄存器写操作

ADDr0,x,1

EORx,r0,x

LDMFDsp!,{r0} //不需要恢复寄存器

}

returnx;

}

将其进行改写,使它符合内联汇编的语法规则。

intf(intx)

{

intr0;

__asm

{

ADDr0,x,1

EORx,r0,x

}

returnx;

}

下面通过几个例子进一步了解内联汇编的语法。

①字符串拷贝

下面的例子使用一个循环完成了字符串的拷贝工作。

#includestdio.h>

voidmy_strcpy(constchar*src,char*dst)

{

intch;

__asm

{

loop:

LDRBch,[src],#1

STRBch,[dst],#1

CMPch,#0

BNEloop

}

}

intmain(void)

{

constchar*a=Helloworld!;

charb[20];

my_strcpy(a,b);

printf(Originalstring:'%s'\n,a);

printf(Copiedstring:'%s'\n,b);

return0;

}





『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
单片机汇编语言 如何实现点亮熄灭二极管