arm汇编语言与c语言,ARM汇编语言和C语言混合编程

f841ea9a3691b407537f68a684aebff6.png

添加r0,r0,r1

MOV pc,LR

......

在C程序的main()函数中调用了add assembly子例程:

extern int add(int x,int y); //声明添加为外部函数

void main(){

int a = 1,b = 2,c;

c =加(a,b); //调用add子例程

......

}

当main()函数调用add Assembly子例程时c语言对应汇编语句,将变量a和b的值赋予r0和r1,并将返回结果由r0带回并分配给变量c. 函数调用结束后,变量c的值为3.

3. C程序中的嵌入式汇编语句

使用C语言的内联汇编语句可以实现一些高级语言无法实现或不容易实现的功能. 对时间要求严格的功能也可以通过将汇编语句嵌入C语言来实现. 内置的汇编器支持大多数ARM指令和Thumb指令,但不支持低级功能,例如直接修改PC以实现跳转,也不能直接使用C语言引用变量.

内联汇编: 以C和C ++语言嵌入汇编语言可以实现一些高级语言无法提供的功能.

语法

__ asm __(;注意: 它前面有两个“ _”

“说明

1e7db2fa5e1a13a9ca9312bcf17d696c.png

...

说明“

); // Linux gcc支持

__ asm {

说明

...

说明

}; //支持ADS

asm(“指令[;指令]”); //用于ARM C ++

ARM嵌入式程序集语法

asm(

汇编语句模板:

输出部分:

输入部分:

编辑部分

);

例如: asm(“ mov%0,%1,ror#1”: “ = r”(结果): “ r”(值));

t01e49dbbad45ed1b.jpg

共有四个部分: 汇编语句模板,输出部分,输入部分,销毁描述部分,每个部分用“: ”分隔,汇编语句模板是必不可少的,其他三个部分是可选的,如果后面的部分是使用,并且前面部分为空,您还需要使用“: ”打开,对应的部分为空. 例如:

__ asm__ __volatile __(

“ CLI”:

: “内存”

);

示例: / * main.c * /

void __main(void)

{

int var = 0xAA;

__ asm //嵌入式程序集徽标

{

MOV R1,var

CMP R1,#0xAA

}

while(1);

}

扩展知识: 汇编语句模板:

1d7443064062b7f02af57501d12b4c9a.png

汇编语句模板由汇编语句序列组成,在语句之间用“;”,“ \ n”或“ \ n \ t”分隔. 指令中的操作数可以使用占位符来引用C语言变量. 操作数最多包含10个占位符,其名称如下: %0,%1 ...,%9.

汇编程序指令,定义为单个字符串常量: “ mov%0,%1,ror#1”

输出部分: 输出部分描述输出操作数. 不同的操作数描述符用逗号分隔. 每个操作数描述符由合格的字符串和C语言变量组成. 每个输出操作数的限定字符串必须包含“ =”,以表明它是一个输出操作数.

“ = r”(结果)

输入部分: 输入部分描述输入操作数. 不同的操作数描述符用逗号分隔. 每个操作数描述符都由限定的字符串和C语言表达式或C语言变量组成.

“ r”(值)

修改部分: 该部分通常使用“内存”作为约束条件c语言对应汇编语句,以指示操作完成后内存的内容已更改. 如果某个寄存器的内容最初来自内存,则内存的单元内容已更改.

asm(代码: outputoperandlist: inputoperandlist: clobberlist);

asm(“ mov%0,%1,ror#1”: “ = r”(结果): “ r”(值));

%0表示“ = r”(结果),%1表示“ r”(值)

生成的汇编语句: 编译器选择registerr3进行位旋转.

它可能还选择了其他任何寄存器.

ldr r3,[sp,#0]

mov r3,r3,ror#1

str r3,[sp,#4]

您可以将volatile属性添加到theasm语句中,以指示编译器不要优化您的汇编代码.

asm volatile(“ mov%0,%1,ror#1”: “ = r”(结果): “ r”(值));

1d112269f5e0b12e13bc092443a02238.png

限制字符: 该函数用于指示编译器如何处理后续C语言变量与指令操作数之间的关系,例如将变量放置在寄存器中还是在内存中等等.

字母含义

m,v,o表示存储单元

R表示任何通用寄存器

Q代表寄存器eax,ebx,ecx,edx之一

I,h表示直接操作数

E,F是浮点数

G表示“任何”

a,b,c,d表示寄存器eax / ax / al,ebx / bx / bl,ecx / cx / cl或edx / dx / dl

S,D表示需要寄存器esi或edi

&输出操作数不能使用与交叉输入操作数相同的寄存器

%此操作数可以与下一个数字交换位置,例如加号

我的意思是常数(0〜31)

以上代码已在ARM ADS 1.2或Linux环境中调试并传递.

总而言之,编译相对简洁,但是功能有限,规则有些零散;

ATPCS功能强大且组织良好,但是需要单独打开一个模块;您可以在编写代码时根据需要自由选择.

代码下载链接:

参考链接:

ATPCS规范:

热爱开源并乐于分享的众神,欢迎加入QQ组: 176507146,您很有价值!

本文来自电脑杂谈,转载请注明本文网址:

http://www.pc-fly.com/a/jisuanjixue/article-195870-1.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值