上一篇讲到赋值运算,这篇讲讲子函数调用。先看最简单范例:test4.c

#include <stdio.h>
void f1()
{
}
void main()
{
int d = 4;
f1();
}

然后编译:arm-linux-gnueabihf-gcc test.c -o test4

然后看看汇编代码:

0000835c <f1>:

1    835c:       b480            push    {r7}

2    835e:       af00            add     r7, sp, #0

3    8360:       46bd            mov     sp, r7

4    8362:       bc80            pop     {r7}

直接跳到main函数里调用此函数时保存的LR值:

5    8364:       4770            bx      lr

6    8366:       bf00            nop



00008368 <main>:

程序用到了r7寄存器,所以须要保护以免破坏之前的数据,同一时候由于本函数调用子函数f1。须要用到lr寄存器保存返回值。故须要保存LR到栈里:



7    8368:       b580            push    {r7, lr}

8    836a:       b082            sub     sp, #8

9    836c:       af00            add     r7, sp, #0

10    836e:       f04f 0304       mov.w   r3, #4

11    8372:       607b            str     r3, [r7, #4]

跳转到函数f1的地址,同一时候把返回地址保存到LR寄存器:

12    8374:       f7ff fff2       bl      835c <f1>

13    8378:       f107 0708       add.w   r7, r7, #8

14    837c:       46bd            mov     sp, r7

注意:此时不再使用bx lr返回了!

而是直接把第7行保存的LR值弹到PC寄存器上,下一条取地址指令就是取main函数的下一个地址。

事实上。採用原来的方式:pop {r7, lr} 以及 bx lr 返回也是能够的。仅仅只是会多使用一条指令:

 15   837e:       bd80            pop     {r7, pc}

细心的人会发现。汇编代码8-11行与《从最简单的实例学习ARM 指令集(一)》中的范例test1.c一模一样。f1函数的机器指令十分简单,就是r7寄存器的压栈与出栈,相信大家都能看懂。

不知道大家有没有注意到,从main函数跳转到f1用的是bl指令,而从f1返回调用的是bx指令?

事实上这是由于涉及到arm处理器的两种工作状态:arm和thumb。子函数返回须要推断lr寄存器的[0]位来决定arm工作在那种状态,对子函数来说。偷懒的做法就是:无论主函数是什么。返回是虽然使用bx。让arm自己推断。而对main函数这样调用者来说。是知道当前处理器工作在thumb还是arm状态的,所以仅仅须要使用bl就能够了。

总结一下子函数的调用规则就是:bl用在函数内。bx用在返回。

下一篇讲讲函数调用过程中。參数是怎样传递的。

从最简单的实例学习ARM 指令集(三)的更多相关文章

  1. ARM指令集学习总结-转载

    ARM指令集比较简单,本文介绍ARM指令集中需要注意和不易理解的地方.       一.ARM指令集是32位的,程序的启动都是从ARM指令集开始,包括所有异常中断都是自动转化为ARM状态,并且所有的指 ...

  2. ARM_Instruction_Set_Encoding_hacking(ARM指令集编码格式解读)

    ARM指令集编码格式解读 说明: 1.本文参考的书籍<ARM Architecture Reference Manual ARMv7-A and ARMv7-R edition>中的Cha ...

  3. 常用 ARM 指令集及汇编

    ARM7TDMI(-S)指令集及汇编 ARM 处理器是基于精简指令集计算机(RISC)原理设计的,指令集和相关译码机制 较为简单,ARM7TDMI(-S)具有 32 位 ARM 指令集和 16 位 T ...

  4. ARM指令集相关知识

    1.ARMv8引入了执行状态机制,分为AArch32和AArch64 AArch32为T32(Thumb)和A32(ARM). AArch64为A64一种指令集 A64和A32的指令都是32位宽,可以 ...

  5. 对arm指令集的疑惑,静态库运行,编译报错等问题

    转载自http://www.jianshu.com/p/4a70aa03a4ea?utm_campaign=hugo&utm_medium=reader_share&utm_conte ...

  6. 实例学习SSIS(三)--使用包配置

    原文:实例学习SSIS(三)--使用包配置 导读: 实例学习SSIS(一)--制作一个简单的ETL包 实例学习SSIS(二)--使用迭代 实例学习SSIS(三)--使用包配置 实例学习SSIS(四)- ...

  7. ARM指令集—SWP指令

    ARM指令集-SWP指令 SWP和SWPB是ARM指令集中对存储单元的原子操作.即对存储单元的一次读和一次不可被切割. SWP和SWPB分别完毕存储器和寄存器之间 一个字(32bit)和一个字节(8b ...

  8. 【基于Android的ARM汇编语言系列】之五:ARM指令集与Thumb指令集

    作者:郭嘉 邮箱:allenwells@163.com 博客:http://blog.csdn.net/allenwells github:https://github.com/AllenWell [ ...

  9. Thumb指令集与ARM指令集的差别

    Thumb指令集          Thumb指令能够看做是ARM指令压缩形式的子集.是针对代码密度[1]的问题而提出的.它具有16为的代码密度.Thumb不是一个完整的体系结构,不能指望处理程序仅仅 ...

随机推荐

  1. Tracing mysqld Using DTrace

    http://dev.mysql.com/doc/refman/5.6/en/dba-dtrace-server.html MySQL 5.6 Reference Manual -> 5 MyS ...

  2. vc 6.0 远程调试

    http://blog.sina.com.cn/s/blog_45eaa01a01014eb5.html

  3. Ubuntu下(Linux+Apache+MYSQL+PHP, LAMP)环境搭建

    近期開始玩PHP,于是试着搭建一下开发环境并做个记录,以备日后再使用起来方便可查. 第一步 确保软件包是最新的 sudo apt-get update 第二步 安装Apache2 sudo apt-g ...

  4. 拆解探索MagSafe电源接口结构和指示灯变颜色原理

    你有没有想过一个Mac的MagSafe接头里面有什么? 控制光线是什么? 在Mac如何知道它是什么样的充电器? 本文探讨的MagSafe连接器内,并回答这些问题. 2006年由苹果公司推出的MagSa ...

  5. idea安装Lombok及使用介绍

    原文:https://blog.csdn.net/motui/article/details/79012846 Lombok使用 介绍 在项目中使用Lombok可以减少很多重复代码的书写.比如说get ...

  6. [原] corePlot 类库与iOS自带类库使用方法对比(很多开源代码都有这个特点)

    ——人类最倚重的是自己的“以往经验”.—— 我们直接看一下在corePlot 类库和iOS自带类中为一个控件设置文本显示格式的实现.   * corePlot 类库中,为一个对象设置标题显示格式 , ...

  7. Appium+python自动化6-Remote远程控制

    前言 在第三篇启动app的时候有这样一行代码driver = webdriver.Remote('http://192.168.1.1:4723/wd/hub', desired_caps),很多小伙 ...

  8. Tomcat 7 的七大新特性

    英文原文:Top 7 Features in Tomcat 7: The New and the Improved Tomcat的7引入了许多新功能,并对现有功能进行了增强.很多文章列出了Tomcat ...

  9. Android之等比例显示图片

    在android中,由于密度的影响,如果想得到图片的宽高是不行的,具体为什么我就大概说一下,具体的请搜索度娘或者古哥吧. 原因是如果你把图片放在drawable-mdpi里,而手机是属于drawabl ...

  10. Python3.6学习笔记(五)

    网络编程 网络程序出现的比互联网要早很多,实现方式主要依靠网络上不同主机间进程的通信,通信协议最重要的是TCP/IP协议.在这两个协议基础上还有很多更高级的协议,包括HTTP.SMTP等.要进行两个主 ...