GNU内联汇编

内联汇编即在C中直接使用汇编语句进行编程,使程序可以在C程序中实现C语言不能完成的一些工作,例如,在下面几种情况中必须使用内联汇编或嵌入型汇编

  1. 程序中使用饱和算术运算(Saturating Arithmetic)
  2. 程序需要对协处理器进行操作
  3. 在C程序中完成对程序状态寄存器的操作
__asm__ __volatile__("asm code":output:input:changed registers);

Note:

  1. 使用__asm____volatile__表示编译器将不检查后面的内容,而是直接交给汇编器。
  2. 如果希望变压器你优化,__volatile__可以不加
  3. 没有asm code也不能省略""
  4. 没有前面的和中间的部分,不可以相应的省略:
  5. 没有changed 部分,必须相应的省略:
  6. 最后的;不能省略,对于C语言来说这是一条语句
  7. 汇编代码必须放在一个字符串内,且字符串中间不能直接按回车换行,可以写成多个字符串,注意中间不能有任何符号,这样就会将两个字符串合并为一个
  8. 指令之间必须要换行,还可以使用\t使指令在汇编中保持整齐

asm code

"mov r0, r0\n\t"
"mov r1,r1\n\t"
"mov r2,r2"

output(asm->C)

:"constraint" (variable)

"constraint"用于定义variable的存放位置:

r表示使用任何可用的寄存器

m表示使用变量的内存地址

+可读可写

=只写

&表示该输出操作数不能使用输入部分使用过的寄存器,只能用"+&""=&"的方式使用

input(C->asm)

:"constraint" (variable/immediate)

"constraint"用于定义variable的存放位置:

r表示使用任何可用的寄存器(立即数和变量都可以)

m表示使用变量的内存地址

i表示使用立即数

例子

int a=100,b=200;
int result;
__asm__ __volatile__(
"mov %0,%3\n\t" //%0是一个占位符,表示result,之后的类推
"ldr r0,%1\n\t"
"ldr r1,%2\n\t"
"str r0,%2\n\t"
"str %1,%1\n\t"
:"=r"(result),"+m"(a),"+m"(b)
:"i"(123)
);

ATPCS

  1. 子程序间通过寄存器R0R3来传递参数,如果参数多于四个,则多出的部分用堆栈传递,被调用的子程序在返回前无须恢复寄存器R0R3的内容
  2. 在子程序中,使用寄存器R4R11来保存局部变量,如果在子程序中使用到了R4R11中的某些寄存器,子程序进入时必须保存这些寄存器的值,在返回前必须恢复这些寄存器的值;对于子程序中没有用到的寄存器则不必进行这些操作,在Thumb程序中,通常只能使用寄存器R4~R7来保存局部变量
  3. R12用作子程序间scrtach寄存器(用于保存SP,在函数返回时使用该寄存器出栈),记作ip
  4. R13用作数据栈指针,记作sp
  5. R14用作连接寄存器,记作lr
  6. R15记作程序寄存器,记作pc

相互调用

C和汇编相互调用要特别注意遵守相应的ATPCS规则

C调用汇编

//.c
#include <stdio.h>
extern void strcopy(char* des, const char* src);
int main(){
const char* srcstr = "src string";
char desstr[]="des string";
strcopy(desstr, srcstr);
return 0;
}
;.asm
.global strcopy
strcopy: ;R0指向目的字符串
;R1指向源字符串
LDRB R2, [R1], #1 ;加载字节并更新源字符串指针地址
STRB R2, [R0], #1 ;存储季节并更新目的字符串指针地址
CMP R2, #0 ;判断是否为字符串结尾
BNE strcopy ;如果不是,程序跳转到strcopy继续循环
MOV pc, ir ;程序返回

汇编调用C

//.c
int fcn(int a, int b , int c, int d, int e){
return a+b+c+d+e;
}
;.asm
;假设程序进入f时,R0中的值为i
;int f(int i){return fcn(i, 2*i, 3*i, 4*i, 5*i);}
.text
.global _start
_start:
STR lr, [sp, #-4]! ;保存返回地址lr
ADD R1, R0, R0 ;计算2*i(第2个参数)
ADD R2, R1, R0 ;计算3*i(第3个参数)
ADD R3, R1, R2 ;计算5*i
STR R3, [SP, #-4]! ;第5个参数通过堆栈传递
ADD R3, R1, R1 ;计算4*i(第4个参数)
BL fcn ;调用C程序
ADD sp, sp, #4 ;从堆栈中删除第五个参数
.end

ARM汇编与C混合编程的更多相关文章

  1. VS2005混合编译ARM汇编代码-转

    原文地址:http://blog.csdn.net/annelcf/article/details/5468093 公司HW team有人希望可以给他们写一个在WinCE上,单独读写DDR的工具,以方 ...

  2. ARM中C和汇编混合编程及示例(转)

    在嵌入式系统开发中,目前使用的主要编程语言是C和汇编,C++已经有相应的编译器,但是现在使用还是比较少的.在稍大规模的嵌入式软件中,例如含有OS,大部分的代码都是用C编写的,主要是因为C语言的结构比较 ...

  3. 九、ARM 汇编与 C 的混合编程

    9.1 ARM 汇编与 C 的混合编程 9.1.1 内嵌汇编 __asm __asm("指令")例如关闭/打开总中断开关 CPSR __asm //使用 C 中变量名代替寄存器 { ...

  4. c语言环境初始化&c语言和汇编混合编程

    bootloader通常会分为两个阶段:第一阶段采用汇编语言来编写,主要是一些核心的初始化工作(内存,时钟的初始化),第二阶段使用C语言来编写,主要是它会完成一些板载硬件的初始化(串口,网口)然后其启 ...

  5. ARM汇编编程基础之一 —— 寄存器

    ARM的汇编编程,本质上就是针对CPU寄存器的编程,所以我们首先要弄清楚ARM有哪些寄存器?这些寄存器都是如何使用的? ARM寄存器分为2类,普通寄存器和状态寄存器 寄存器类别 寄存器在汇编中的名称 ...

  6. 3.1 ARM汇编编程概述

    1. 汇编编程 为什么要学习汇编 1). Bootloader初始化 2). Linux kernel 3). 高效 2. ARM汇编分类 1. ARM标准汇编:ARM公司得汇编器适合在Windows ...

  7. ARM汇编编程概述

    1.为什么需要学些汇编指令 2.ARM汇编指令分类 3.汇编程序框架 4.编程准备 +++++++++++++++++++++++++++++++++++ 1.为什么需要学些汇编指令 bootload ...

  8. C51与汇编混合编程详解

    C51和汇编混合编程(1)-C语言中嵌入汇编 1.在 C文件中要嵌入汇编代码片以如下方式加入汇编代码: #pragma ASM ;Assembler Code Here #pragma ENDASM ...

  9. 【转】VxWorks中高精度实时时钟的实现及C语言汇编混合编程

    最近一个项目中需要在VxWorks下使用一个高精度实时时钟,要求精度为1ms,溢 出时间大于5小时.VxWorks提供系统时钟,该时钟在操作系统启动后开始计数,精度为1个tick,可以通过tickGe ...

随机推荐

  1. C#字符串的不变性

    看过一些C#教程的人都应该知道这句话:“在C#中,一旦对字符串对象进行初始化,该字符串对象就不能再被该变“.这句话可用简单的图示来说明: 1.声明变量 string str="first&q ...

  2. LINQ to SQL语句(12)之Delete和使用Attach

    1.简单形式 说明:调用DeleteOnSubmit方法即可. OrderDetail orderDetail = db.OrderDetails.First (c => c.OrderID = ...

  3. Android封装OkHttpClient的类库

    由于android6.0的SDK没有HttpClient,只有HttpURLConnection和OkHttpClient,特记下OkHttpClient的使用方法 1.Ui测试界面布局 <?x ...

  4. MVC调试时遇到的URL问题

    最近接手一个项目时遇到了点问题,事情是这样的,本人拿到源码准备F5准备试跑看一下,原本是应该打开 http:/localhost/Home/Login,结果程序直接跳到 http://localhos ...

  5. 【C#进阶系列】26 计算限制的异步操作

    什么是计算限制的异步操作,当线程在要使用CPU进行计算的时候,那么就叫计算限制. 而对应的IO限制就是线程交给IO设备(键鼠,网络,文件等). 第25章线程基础讲了用专用的线程进行计算限制的操作,但是 ...

  6. DecoratorPattern(装饰器模式)

    /** * 装饰者模式 * @author TMAC-J * 总的来说,装饰者模式就是继承的应用 */ public class DecoratorPattern { interface Beans{ ...

  7. java实现链表

    单链表 package com.voole.linkedlist; public class Test { public static void main(String[] args) { Linke ...

  8. eclipse js 报错解决办法

    最近项目中的js一直红叉叉,本人本来就是那种看见回收站有东西想清理的那种强迫症患者, 所以对于这种红叉叉更是心烦.这个我已经忍了好久了.今天 见这哥们犀利的解决了这个eclipes的bug.很是激动, ...

  9. HTML5定稿

    HTML5定稿了,终于有一种编程语言开发的程序可以在Android和IOS两种设备上运行了 本文转载自: http://www.cnblogs.com/tuyile006/p/4103634.html ...

  10. 基于 Angularjs&Node.js 云编辑器架构设计及开发实践

    基于 Angularjs&Node.js 云编辑器架构设计及开发实践 一.产品背景 二.总体架构 1. 前端架构 a.前端层次 b.核心基础模块设计 c.业务模块设计 2. Node.js端设 ...