ARM汇编与C混合编程

时间:2021-12-05 03:05:41

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语言环境初始化&amp&semi;c语言和汇编混合编程

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

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

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

  6. 3&period;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. 【Pyrosim案例】01:空气流动

    1 案例说明 Pyrosim是一款FDS前后处理软件.以一个非常简单的案例来描述Pyrosim的工作流程.本案例计算域中包含一个空气入口,一个环境出口. 案例主要演示以下内容: 创建Vents 增加切 ...

  2. 升级NC6&period;3

    2014-04-23 江苏建工&用友公司会谈提纲 1,合同规定江苏建工用友NC在实施成功之后三年免服务费(2010年增补了资金管理,如果以2010年作为软件最终实施完成,那么2010-2013 ...

  3. mac 下 php 安装 中的坑

    brew Error: Formulae found in multiple taps http://www.trylife.cn/brew-error-formulae-found-in-multi ...

  4. Codeforces 204A Little Elephant and Interval

    http://codeforces.com/problemset/problem/204/A 题意:给定一个[L,R]区间,求这个区间里面首位和末尾相同的数字有多少个 思路:考虑这个问题满足区间加减, ...

  5. 不完全图解HTTP

    在2D平面上行走的时候,认识只局限于“点”,刚认识一个新的点,就把之前的那个点忘记了,捡了芝麻丢西瓜.只从3D视角俯瞰时,把这些点连接在一起,点成线,线成面时,才能有所顿悟.话不多说,这是我对HTTP ...

  6. 基于Windows下python3&period;4&period;1IDLE常用快捷键小结

    安装IDLE后鼠标右键点击*.py 文件,可以看到Edit with IDLE 选择这个可以直接打开编辑器.IDLE默认不能显示行号,使用ALT+G 跳到对应行号,在右下角有显示光标所在行.列.ALT ...

  7. CentOS7&period;6 安装Docker

    删除已安装的Docker # Uninstall installed docker sudo yum remove docker \ docker-client \ docker-client-lat ...

  8. BZOJ1263 &lbrack;SCOI2006&rsqb;整数划分 高精度

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1263 题意概括 将n写成若干个正整数之和,并且使这些正整数的乘积最大. 例如,n=13,则当n表示 ...

  9. CAP定理为什么只能同时满足两个

    Consistency(一致性), 数据一致更新,所有数据变动都是同步的 Availability(可用性), 好的响应性能 Partition tolerance(分区容忍性) 可靠性 在网上看了很 ...

  10. HDU - 1525

    题意:给你两个数,a,b,有两个人轮流进行一次操作, 每次操作可以将大的数减去k倍的小的数,最后不能操作的人输了,问你谁赢了. 思路:我们可以用辗转相除法求出对于每一个状态可以改变几次,这样问题就变成 ...