首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

arm gcc内嵌汇编

arm gcc内嵌汇编

高级语言可以实现大部分编程功能,但是当我们需要对特定代码进行优化,写启动代码,或者操作特定

硬件,或需要直接用CPU指令等等操作的时候我们需要用到汇编。但是我们只想在高级语言(比如C语言

)中的某些特定部分插入某些汇编指令,这时候,我们就需要用高级语言提供的内嵌汇编功能。我们以

arm gcc为例,用arm gcc进行c语言和汇编语言混合编程。

最简单的内嵌汇编:


#include <stdio.h>


int main( int argc, char ** argv )

{

        asm("nop");

}

上面就一条内嵌汇编指令:asm("nop");nop指令在汇编上表示执行空操作,消耗一个CPU指令周期。(实

际上nop是一条伪指令,会被编译起翻译成: mov r0, r0这条真实cpu指令)


内嵌汇编的通用形式:


r0-r3


asm (

代码
r0-r3

: 输出操作数列表

: 输入操作数列表

: 破坏列表

);

在一个asm语句中可以写一条或者多条汇编代码,一条汇编代码结束采用\n进行换行,有时候,也采用

\n\t进行换行。C语言通过变量的形式访问数据,而汇编语言是通过内存地址或者直接访问寄存器的方

式访问数据,如果要在内嵌汇编中访问C语言中的变量,并且修改它的值的话,那么就需要用一种方式

用于相互转换C语言的变量与内嵌汇编能访问的寄存器或内存地址形式。这种方式就是通过输入操作数

列表和输出操作数列表实现的。

输入和输出操作数列表的格式是一样的,都是由一个或者多个操作数组成,中间采用逗号进行分开,单

个操作的格式如下:


[C变量在汇编中的访问名称] "限制性字符“ (C传递进来的变量名称)


例如,下面程序是实现从C语言中传递2个变量a,b进入汇编中,然后在汇编中实现a+b,把结果存回变量C

中:

#include <stdio.h>

int main( int argc, char ** argv )
{
        int a = 20, b = 30;
        int c;

        asm (
                "add %[cc], %[aa], %[bb]"
                : [cc] "=r" (c)
                : [aa] "r" (a), [bb] "r" (b)

: "memory"
   
);

        printf("c = %d\n", c );
        return 0;
}
~      
上面代码没有破坏列表,可以省略不写。上面汇编中,输入了C语言中的变量a和b,执行结果输出到变

量c中,在汇编中访问C语言中的变量a,b,c通过%[aa],%[bb],%[cc]进行访问的。当传递常量,指针,或

者变量到内嵌汇编中,内嵌汇编必须知道如何在汇编代码中表示他们,这个就是由中间“限制性字符”

来指定。

常用限制性字符:


I: 立即数
例如: [changliang] "I" (120), 表示把120作为立即

数的方式传递进去。

m: 任何有效内存
例如: [nc] "m" (a) , 表示把变量a的地址传递到内嵌汇编中,

str r0, %[nc], 就表示把r0的值存入变量a。

r: 通常的寄存器(r0-r15)。最常用。

上面这些限制性字符如果不带修饰符的话,表示是只读操作数,只能用于输入操作数列表中。对于输出

操作数列表中的操作数我们需要加上相应的写权限。常用修饰符包括如下:


= 只写操作数,通常用于所有的输出操作数。

+ 读写操作。

& 只用作输出的寄存器。(表示不能与输入寄存器用同样一个寄存器)


破坏列表:


一般就是一个“memory",或者寄存器列表。如果在汇编代码中修改了内存中的值,我们就需

要在破坏列表中加上"memory"字段,告诉编译器,我们修改了内存中的值。如果在汇编代码中修改了某

些寄存器,那么我们就需要把在代码中所修改过的寄存器列在破坏列表中。



防止编译器优化:


为了不让编译器优化我们的代码,比如,本来我们想在汇编中采用nop指令进行延时,然后,

通常情况下编译起会把nop当成一条无用指令而优化掉它,为了防止编译器优化,我们需要在asm语句符

号后面加上__volatile__,这样就可以防止编译器优化我们的汇编代码。


asm __volatile__ ();
继承事业,薪火相传
返回列表