如下,一个简单的程序

 #include <stdio.h>
int add(int a, int b)
{
return a + b;
} void main()
{
int a = , b = ;
int result;
result = add(a, b);
printf("%d",result);
}

执行反汇编指令:gcc -g test.c
objdump -S

得到x86机器的汇编代码(除去一些初始化的代码)如下:

在分析上面的汇编程序之前,需要了解rbp、rsp为栈基址寄存器、栈顶寄存器,分别指向栈底和栈顶;edx、eax、esi、edi均为x86CPU上的通用寄存器,可以存放数据(虽然它们还有别的作用,但是本文章不涉及)

x86下栈生长是从高地址往低地址,即push操作一次,rsp减少4个字节,pop操作一次,rsp增加4个字节。

对上面汇编代码的分析:

进入main函数,保护现场,将rbp压入堆栈;

然后为main函数开拓新的堆栈框架,rbp与当前rsp相同,rsp再向上扩充16个字节(0x10);(以前的C程序只能在函数前面声明变量,是因为编译器还么有那么“智能”,它只能通过分析前部分的变量,一次性的为程序扩充堆栈)

然后向栈底上方的偏移地址为8和12的单元存入数据1和2;

把数据送入通用寄存器中,以供新的函数调用;

跳转到add;

再次将main的rbp压栈,保护;

新的rbp与当前rsp相同,把通用寄存器中的数据赋给栈底上方偏移地址为4和8的单元(此为函数参数传递的关键);

将传入新栈的参数赋给通用寄存器,进行加法操作,结果存入eax;

pop出rbp,回到main函数;

将eax中的运算结果赋给栈底上方偏移地址为4的单元;

然后调用printf函数显示结果。

使用arm-linux-gcc编译并反汇编:arm-linux-objdump -D -m arm a.out

得到arm机器的汇编代码(除去一些初始化的代码)如下:

这段代码的解析与x86类似,只不过需要了解几个arm汇编指令和寄存器名称。fp为帧寄存器,起“标签”作用。lr是连接寄存器,在ARM体系结构中lr的用途有两种:一是用来保存子程序返回地址;二是当异常发生时,lr保存的值等于异常发生时PC的值减4(或者减2),因此在各种异常模式下可以返回到异常发生前的相应位置继续执行。bx lr即跳转到lr存放的地址处。sp为栈顶指针。str 源寄存器 存储地址,即将源存储器数据送到存储器中,ldr为其逆操作。

ARM为堆栈提供硬件支持,它有一个专门的寄存器sp指向栈顶,ARM支持四种堆栈工作方式,最常用的也是和x86类似,即从高地址向低地址生长。

参考资料:http://mooc.study.163.com/course/USTC-1000029000#/info

通过反汇编理解函数调用机制(x86和ARM)的更多相关文章

  1. Linux Debugging(一): 使用反汇编理解C++程序函数调用栈

    拿到CoreDump后,如果看到的地址都是????,那么基本上可以确定,程序的栈被破坏掉了.GDB也是使用函数的调用栈去还原"事故现场"的.因此理解函数调用栈,是使用GDB进行现场 ...

  2. 你好,C++(25)函数调用和它背后的故事5.1.2 函数调用机制

    5.1.2  函数调用机制 在前面的学习中,我们多次提到了“调用函数”的概念.所谓调用函数,就是将程序的执行控制权从调用者(某个函数)交给被调用的函数,同时通过参数向被调用的函数传递数据,然后程序进入 ...

  3. QtCreator动态编译jsoncpp完美支持x86和arm平台

    如果是做嵌入式开发. 在Qt下支持JSon最好的办法,可能不是采用qjson这个库.QJson这个库的实例只提供了x86环境下的编译方法. Installing QJson-------------- ...

  4. 理解session机制

    理解session机制 session机制是一种服务器端的机制,服务器使用一种类似于散列表的结构(也可能就是使用散列表)来保存信息. 当程序需要为某个客户端的请求创建一个session的时候,服务器首 ...

  5. 第二十节: 深入理解并发机制以及解决方案(锁机制、EF自有机制、队列模式等)

    一. 理解并发机制 1. 什么是并发,并发与多线程有什么关系? ①. 先从广义上来说,或者从实际场景上来说. 高并发通常是海量用户同时访问(比如:12306买票.淘宝的双十一抢购),如果把一个用户看做 ...

  6. Linux系统下x86和ARM的区别有哪些?

    问题: 最近在用三星的一款i5处理器的Windows平板,和iPad,以及其他使用ARM处理器的手机相比,发热量大很多,甚至需要借助风扇来散热,耗电量也大了不少. 那么就很奇怪,在主频相差不大,并且实 ...

  7. (白话理解)CAS机制

    (白话理解)CAS机制 通过一段对话我们来了解cas用意 示例程序:启动两个线程,每个线程中让静态变量count循环累加100次. 最终输出的count结果是什么呢?一定会是200吗? 加了同步锁之后 ...

  8. qt 维护x86和arm两套编译环境

    1.中间库: 中间库都放在middlewares目录,include头文件相同,所以不需要特殊处理,只要特殊处理lib安装目录, 示例pro文件如下: TEMPLATE = lib TARGET = ...

  9. [转帖]Linux系统下x86和ARM的区别有哪些?

    Linux系统下x86和ARM的区别有哪些? https://www.cnblogs.com/alantu2018/p/9209143.html 其实界限 越来越小了.. 问题: 最近在用三星的一款i ...

随机推荐

  1. SQL SERVER 2008配置Database Mail –用SQL 数据库发邮件

    SQL SERVER 2008配置Database Mail –用SQL  数据库发邮件 https://blogs.msdn.microsoft.com/apgcdsd/2011/06/28/sql ...

  2. 腾讯优测干货精选|Android双卡双待适配——隐藏在数据库中的那些秘密

    腾讯优测是专业的app自动化测试平台,除了提供兼容性测试,远程真机租用等多维度的测试服务,还有优分享-腾讯内部的移动研发测试干货精选~ 许多APP都希望获取用户通讯录联系人,利用通讯录关系链信息来丰富 ...

  3. threadpool 的配置实用

    //spring mvc文件中的配置 <!-- ThreadPoolExecutor --> <bean id="threadPoolTaskExecutor" ...

  4. c++作用域运算符---7

    原创博客:转载请标明出处:http://www.cnblogs.com/zxouxuewei/ ::是C++里的“作用域运算符”. 比如声明了一个类A,类A里声明了一个成员函数void f(),但没有 ...

  5. python百分比数比较大小

    python是无法识别百分比的,估计你的百分比是string,所以需要转成int # !/usr/bin/python3.4 # -*- coding: utf-8 -*- # 百分数转为int de ...

  6. HTML5播放器

    seweise palyer http://www.whatled.com/m/?post=1626 https://github.com/sewise/sewise-player2 七牛云音视频支持 ...

  7. 通过Oracle补充日志,找到锁阻塞源头的SQL

    问题背景: 有时会考虑一件事情,如果在Oracle环境下出现了锁阻塞的情况,如何定位到SQL源头(通过session.lock.transaction等视图仅能定位到会话)?或许有人会想有没有可能通过 ...

  8. 从jsTree演示代码中提取的在线文件查看

    从jsTree演示代码中提取的在线文件查看 jsTree 请参考:https://www.jstree.com/ 效果如下: 代码下载:http://files.cnblogs.com/files/z ...

  9. bzoj4130: [PA2011]Kangaroos

    Description 定义两个区间互相匹配表示这两个区间有交集. 给出长度为N的区间序列A,M次询问,每次询问序列A中最长的连续子序列,使得子序列中的每个区间都与[L,R]互相匹配 N<=50 ...

  10. 物流公司统计按物资类别采购的前二十家sql

    2.集团主要的供应商(按物资分类列举前10或20家名单),年采购金额.占比,结算方式,付款周期:(夏) 年份要求是2013年 arap_djfb中的单据日期不是常规的日期类型 需要做这样的转换才可以 ...