从最简单的实例学习ARM 指令集(三)
上一篇讲到赋值运算,这篇讲讲子函数调用。先看最简单范例: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 指令集(三)的更多相关文章
- ARM指令集学习总结-转载
ARM指令集比较简单,本文介绍ARM指令集中需要注意和不易理解的地方. 一.ARM指令集是32位的,程序的启动都是从ARM指令集开始,包括所有异常中断都是自动转化为ARM状态,并且所有的指 ...
- ARM_Instruction_Set_Encoding_hacking(ARM指令集编码格式解读)
ARM指令集编码格式解读 说明: 1.本文参考的书籍<ARM Architecture Reference Manual ARMv7-A and ARMv7-R edition>中的Cha ...
- 常用 ARM 指令集及汇编
ARM7TDMI(-S)指令集及汇编 ARM 处理器是基于精简指令集计算机(RISC)原理设计的,指令集和相关译码机制 较为简单,ARM7TDMI(-S)具有 32 位 ARM 指令集和 16 位 T ...
- ARM指令集相关知识
1.ARMv8引入了执行状态机制,分为AArch32和AArch64 AArch32为T32(Thumb)和A32(ARM). AArch64为A64一种指令集 A64和A32的指令都是32位宽,可以 ...
- 对arm指令集的疑惑,静态库运行,编译报错等问题
转载自http://www.jianshu.com/p/4a70aa03a4ea?utm_campaign=hugo&utm_medium=reader_share&utm_conte ...
- 实例学习SSIS(三)--使用包配置
原文:实例学习SSIS(三)--使用包配置 导读: 实例学习SSIS(一)--制作一个简单的ETL包 实例学习SSIS(二)--使用迭代 实例学习SSIS(三)--使用包配置 实例学习SSIS(四)- ...
- ARM指令集—SWP指令
ARM指令集-SWP指令 SWP和SWPB是ARM指令集中对存储单元的原子操作.即对存储单元的一次读和一次不可被切割. SWP和SWPB分别完毕存储器和寄存器之间 一个字(32bit)和一个字节(8b ...
- 【基于Android的ARM汇编语言系列】之五:ARM指令集与Thumb指令集
作者:郭嘉 邮箱:allenwells@163.com 博客:http://blog.csdn.net/allenwells github:https://github.com/AllenWell [ ...
- Thumb指令集与ARM指令集的差别
Thumb指令集 Thumb指令能够看做是ARM指令压缩形式的子集.是针对代码密度[1]的问题而提出的.它具有16为的代码密度.Thumb不是一个完整的体系结构,不能指望处理程序仅仅 ...
随机推荐
- ecshop功能目录
右上 开店向导 1设置商店的一些基本信息 商店的名字.地址.配送方式.支付方式等 2给商店添加一些商品 商品的名称.数量.分类.品牌.价格.描述等 3恭喜您,您的网店可以使用了!下面是一些常用功能的链 ...
- Jenkins搭建.NET自动编译测试与发布环境
本文地址: http://blog.csdn.net/wangjia184/article/details/18365553 操作系统Windows, 确保需要的.NET Framework已经安装 ...
- springMVC 前台向后台传数组
前台: $(function() {//点击播放按钮执行的事件 $("#button").click(function(e) { alert("kaishi chuanz ...
- PHP中的 变量 与 常量 详解
几乎所有的编程语言都会涉及到变量和常量这两个概念,PHP也不例外.本节将介绍PHP语言中的变量和常量的应用方法. 一.什么是变量和常量 在程序执行的过程中,变量存储的值可以随时改变,而常量存储的值是不 ...
- 用最简单的例子理解模板方法模式(Template Method Pattern)
假设要做一道红烧肉,做法有很多,在不同的做法中都有相同的部分,比如都要放油.放肉.放调料等.也有不同之处,比如有些做法放可乐,有些做法放甜蜜酱,等等. 先提炼出一个抽象类,该类不仅有制作红烧肉的各个步 ...
- MVC二级联动使用$.getJSON方法
本篇使用jQuery的$.getJSON()实现二级联动. □ View Models 1: namespace MvcApplication1.Models 2: { 3: public cla ...
- java操作mongodb时,对象bean和DBObject相互转换的方法
package com.iqbon.spider.util; import java.lang.reflect.Field; import java.lang.reflect.InvocationTa ...
- 混沌数学之Henon吸引子
Henon吸引子是混沌与分形的著名例子. 相关软件:混沌数学及其软件模拟相关代码: // http://wenku.baidu.com/view/d51372a60029bd64783e2cc0.ht ...
- iOS开发-UIWebView加载本地和网络数据
UIWebView是内置的浏览器控件,可以用它来浏览网页.打开文档,关于浏览网页榜样可以参考UC,手机必备浏览器,至于文档浏览的手机很多图书阅读软件,UIWebView是一个混合体,具体的功能控件内置 ...
- eclipse 使用Maven deploy命令部署构建到Nexus上 【二】
http://blog.csdn.net/jun55xiu/article/details/43051627