一. 汇编调用 C

  1. 初始化栈

  2. 初始化BSS段 (BSS 段是C语言存放未初始化的全局变量,或者初始化为0 的全局变量)

  3 .使用 r0 ,r1, r2, r3 给函数传参,如果多于  4 个参数使用栈的方式传参

  4. 返回值放在 r0, r1 中,最大32位数据, 一般使用 r0 就可以满足要求

例子: 汇编文件 start.s

.text  @ 表示汇编文件开始

/****初始化栈*****/
ldr sp, =0x40000100
mov r0, #0x5
mov r1, #0x6 /***初始化bss段***/
@ bss段地址由链接时编译器分配
ldr r2, =__bss_start @ BSS 起始地址
ldr r3, =__bss_end__ @ BSS 结束地址
mov r4, #0x00000000 clbss_l:
teq r2, r3 @ r2, r3 中存放的是BSS段起始和结束地址
strne r4, [r2] @ 把r4 中的数据写入 r2中存放的地址中,teq结果不成立写入,也就是把bss段写0
addne r2, r2, # @ 起始地址开始偏移一个字节,teq不成立的清苦下
bne clbss_l @ teq 不成立,表示还没有清除完bss 段, bl _main @ 跳转到执行的C 函数名 .end @ 伪操作 , 表示汇编文件结束

main.c

int aa;
int _main(int a, int b)
{
int t=0;
t = a+ b;
return t;
}

链接文件: map.lds

OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
/*OUTPUT_FORMAT("elf32-arm", "elf32-arm", "elf32-arm")*/
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
. = 0x00000000;
. = ALIGN();
.text :
{
./Objects/start.o(.text)
*(.text)
}
. = ALIGN();
.rodata :
{ *(.rodata) }
. = ALIGN();
.data :
{ *(.data) }
. = ALIGN();
__bss_start = .;
.bss :
{ *(.bss) }
__bss_end__ = .;
}

测试: 申请一个全局变量,int aa; 占4字节的BSS 段所以起始和结束地址相差4 字节,所以会在清楚BSS 执行循环4次

二. C调用汇编

C 语言调用 汇编时 只要汇编实现的函数通过 .global 声明成全局函数即可在 C语言中调用

关于参数的传递:

  C 函数的参数,传递给汇编放在寄存器 r0,r1,r2,r3 中;汇编会使用 寄存器 r0 接受调用汇编函数的返回值

  

例子: start.s汇编文件

.text

/****初始化栈*****/
ldr sp, =0x40000100
mov r0, #0x5
mov r1, #0x6 /* 汇编跳转到 C 中 */
/* 初始化bss段 */
@ bss段地址由链接时编译器分配
ldr r2, =__bss_start @ BSS 起始地址
ldr r3, =__bss_end__ @ BSS 结束地址
mov r4, #0x00000000 clbss_l:
teq r2, r3 @ r2, r3 中存放的是BSS段起始和结束地址
strne r4, [r2] @ 把r4 中的数据写入 r2中存放的地址中,teq结果不成立写入,也就是把bss段写0
addne r2, r2, # @ 起始地址开始偏移一个字节,teq不成立的清苦下
bne clbss_l @ teq 不成立,表示还没有清除完bss 段, bl _main @ 跳转到执行的C 函数名 , lr 中会保存下一条指令的地址, 也就是
b loop /* 汇编函数, 在C 中调用 */
.global add_fun @ 声明为全局函数,使外部可调用
add_fun:
add r2, r1, r0 @ 把 r1和r0中的数据相加 放在r2 中
mov r0, r2    @ 使用寄存器 r0 存放调用汇编函数时返回的结果
mov pc, lr    @ lr 寄存器中保存 C 跳转到汇编时的下一条指令地址 , 重新付给 PC 继续执行loop:
b loop .end

测试:

ARM 汇编与C之间 的调用的更多相关文章

  1. ARM 汇编与C调用的若干问题(一般函数调用情况)

    ARM 汇编与C之间的函数调用需要符合ATPCS,建议函数的形参不超过4个,如果形参个数少于或等于4,则形参由R0,R1,R2,R3四个寄存器进行传递:若形参个数大于4,大于4的部分必须通过堆栈进行传 ...

  2. arm汇编进入C函数分析,C函数压栈,出栈,传参,返回值

    环境及代码介绍 环境和源码 由于有时候要透彻的理解C里面的一些细节问题,所有有必要看看汇编,首先这一切的开始就是从汇编代码进入C的main函数过程.这里不使用编译器自动生成的这部分汇编代码,因为编译器 ...

  3. GNU风格 ARM汇编语法指南

    汇编源程序一般用于系统最基本的初始化:初始化堆栈指针.设置页表.操作 ARM的协处理器等.这些初始化工作完成后就可以跳转到C代码main函数中执行. 1.  GNU汇编语言语句格式 任何Linux汇编 ...

  4. 常用ARM汇编指令

    常用ARM汇编指令 [日期:2012-07-14] 来源:Linux社区  作者:xuyuanfan77 [字体:大 中 小]     在嵌入式开发中,汇编程序常常用于非常关键的地方,比如系统启动时初 ...

  5. ARM 汇编的一些规范

    A.5.1  文件格式        ARM 源程序文件(即源文件)为文件格式,可以使用任一文本编辑器编写程序代码.         在一个项目中,至少要有一个汇编源文件或C 程序文件,可以有多个汇编 ...

  6. 经常使用ARM汇编指令

    一面学习,一面总结,一面记录. 以下是整理在网上找到的一些资料,简单整理记录一下,方便以后查阅. ARM处理器的指令集能够分为跳转指令.数据处理指令.程序状态寄存器(PSR)处理指令.载入/存储指令. ...

  7. ARM汇编关键知识点总结(转)

    1.LDR R1, =COUNT 意思是将 COUNT 变量的地址放到 R1中LDR R1, COUNT 意思是将 COUNT 变量地址里面的内容赋给 R1 2. Load-Store 结构——这个应 ...

  8. ARM汇编学习笔记

    ARM  RISC  (Reduced Instruction Set Computers) X86   CISC  (Complex Instruction Set Computers)      ...

  9. ARM汇编初探---汇编代码中都有哪几类指令---ARM伪指令介绍

    要学习一个东西首先要把概念搞清楚,以下仅仅是自己的一些关于汇编的理解. 可运行文件里的01码是机器码,机器码不等于汇编码,尽管机器码能够非常easy翻译成汇编码. 汇编码中包括非常多汇编指令.伪指令和 ...

随机推荐

  1. 任正非:5G技术只独家卖给美国!不卖给韩国、日本、欧洲

    https://v.qq.com/x/page/g3001d0xvxe.html 我只转个标题,细节不管了. 呃,实际上就是说,老任头也决定向美国低头了,对不. 不过,也确实没办法. 该起床吃钙片了.

  2. Python之字符串转换为日期、结合时区的日期操作

    一.字符串转换为日期 方法一 s = '2019-01-20' print(datetime.strptime(s, '%Y-%m-%d')) # 2019-01-20 00:00:00 方法二 de ...

  3. SQL数据库—<6-001> 常用系统存储过程大全 --摘录网

    -- 来源于网络 -- 更详细的介结参考联机帮助文档 xp_cmdshell --*执行DOS各种命令,结果以文本行返回. xp_fixeddrives --*查询各磁盘/分区可用空间 xp_logi ...

  4. 【知识强化】第四章 网络层 4.8 移动IP

    这节课我们来学习一下移动IP. 那移动IP呢要跟动态IP区分开.动态IP是指,通过使用DHCP协议,在一个局域网内部的一台主机,就可以动态地获得一个IP地址.那这里面的移动IP是什么意思呢? 我们来举 ...

  5. tomcat manager详解

    Tomcat Manager是Tomcat自带的.用于对Tomcat自身以及部署在Tomcat上的应用进行管理的web应用.Tomcat是Java领域使用最广泛的服务器之一,因此Tomcat Mana ...

  6. 59th python下graphviz安装 砖

    原文 摘录  感谢分享:   https://www.cnblogs.com/liusx0303/p/9155305.html 参考链接:https://blog.csdn.net/u01325041 ...

  7. react-native学习(一)————使用react-native-tab-navigator创建底部导航

    使用react-native-tab-navigator创建底部Tab导航 1.使用npm安装react-native-tab-navigator npm install react-native-t ...

  8. JavaSE---main方法解读

    1.概述 1.1 java程序入口:main方法 public static void main(String[] args){} a,public:java类由JVM调用,为了让JVM自由调用mai ...

  9. 【和孩子一起学编程】 python笔记--第一天

    [该随笔记录本人在阅读过程写的笔记和一些问题,格式比较随意,不定时更新] 由于该书使用的python版本为2.5,本人使用的为3.6. 第一章: 遇到的第一个问题: 1.3节 输出指令: print ...

  10. 【Flutter学习】之绘画实例(二)

    一,画路径 - drawPath(Path path, Paint paint)  Path 主要有方法如下: 直接描述路径的方法还可以细分为两组:添加子图形和画线(直线或曲线) addXXX() - ...