浅析ARM架构下的函数的调用过程

浅析ARM架构下的函数的调用过程

ARM函数调用基本流程

ARM函数调用的基本流程如下:

  1. 调用者保存寄存器(Callee saved registers):在调用函数之前,调用者需要保存被调用者需要用到的寄存器,否则这些值会被调用函数所覆盖,导致逻辑错误。在ARM架构中,callee saved registers 都是 r4-r11,他们将被保存在当前堆栈帧中。

  2. 传递参数:函数调用需要传递参数给函数,ARM架构中使用寄存器 r0-r3 来传递前4个参数,超出4个参数时需要通过栈来传递。

  3. 跳转到被调用函数:使用 bl 指令跳转到被调用函数入口地址。

  4. 被调用函数处理:被调用函数处理时需要处理参数,所以需要使用 r0-r3 从调用函数中读取参数,然后在处理过程中需要保存callee 保存寄存器,然后完成处理。

  5. 返回结果:函数返回时将在r0中放置返回值,然后使用 bx lr指令跳转回调用函数的地址,同时恢复callee saved registers。

例子1

下面是一个简单的C函数,实现对传入参数x和y的加法运算。它的伪代码如下:

void add(int x, int y){
  return x + y;
}

我们编写如下的ARM汇编代码来实现它:

    // Definition of function 'add'
    add:
        //保存callee saved registers
        push    {r4-r7, lr}

        //将参数保存到r4和r5中
        mov     r4, r0
        mov     r5, r1

        //调用add函数进行加法运算
        add     r0, r4, r5

        //恢复callee saved registers
        pop     {r4-r7, lr}

        //返回
        bx      lr

在这个例子中,我们使用了 r4 和 r5 寄存器来保存传入的参数,使用了 r0 来存储函数的返回值。

例子2

下面是一个更加复杂的函数调用例子。我们假设有两个函数 foo 和 bar,其中 foo 调用了 bar 函数。 伪代码如下:

int bar(int x, int y) {
    return x * y;
}

int foo(int x, int y, int z) {
    int val = bar(x, y);
    return val + z;
}

我们编写如下的ARM汇编代码来实现这两个函数:

    // Definition of function 'bar'
    bar:
        //保存callee saved registers
        push    {r4-r7, lr}

        //参数保存
        mov     r4, r0
        mov     r5, r1

        //运算
        mul     r0, r4, r5

        //callee saved registers 恢复
        pop     {r4-r7, lr}

        bx      lr

    // Definition of function 'foo'
    foo:
        //callee saved registers 保存
        push    {r4-r7, lr}

        //bar函数的第一个参数
        mov     r4, r0
        mov     r5, r1

        //bar函数的调用
        bl      bar

        //bar函数的返回值的存在的地址
        mov     r6, r0

        //将第三个参数保存到r0中
        mov     r0, r2

        //callee saved registers 恢复
        pop     {r4-r7, lr}

        //返回最终值,r6 存储了 bar(x,y) 的返回值
        add     r0, r6, r0
        bx      lr

在这个例子中,我们使用了 r4 - r7 的寄存器来保存callee saved registers,使用了 r0 - r5 来传递参数,使用了 r6 来保存 bar 函数的返回值。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:浅析ARM架构下的函数的调用过程 - Python技术站

(0)
上一篇 2023年5月23日
下一篇 2023年5月23日

相关文章

  • Windows配置VSCode+CMake+Ninja+Boost.Test的C++开发环境(教程详解)

    下面是“Windows配置VSCode+CMake+Ninja+Boost.Test的C++开发环境(教程详解)”的完整攻略: 介绍 在Windows系统下,配置C++开发环境需要一些必须的组件和软件。本文将介绍如何在Windows系统下安装和配置VSCode、CMake、Ninja和Boost.Test组件,从而打造一个完整的C++开发环境。 步骤一:安装…

    C 2023年5月23日
    00
  • vs2019+cmake实现Linux远程开发的方法步骤

    以下是详细讲解“vs2019+cmake实现Linux远程开发的方法步骤”的完整攻略,包括两个示例说明。 一、背景介绍 随着开源技术的普及,越来越多的开发者开始使用Linux系统进行开发。但是,有些Windows操作系统的用户可能会遇到一些困难,比如需要将代码从Windows系统复制到Linux系统中进行编译和运行,或者在Windows系统上开发的代码需要在…

    C 2023年5月23日
    00
  • Java开发工具-scala处理json格式利器-json4s详解

    Java开发工具-scala处理json格式利器-json4s详解 简介 JSON是现代API和Web应用程序的标准格式,但是到目前为止,处理JSON数据更具体地讲就是解析和构造高效且易读的代码仍然是一项难题。而Scala是一种现代化而又灵活的编程语言,而json4s是Scala处理和解析JSON数据的十分有用的库。 在本文中,我们将讨论如何使用Scala的…

    C 2023年5月23日
    00
  • 深入理解C/C++混合编程

    深入理解C/C++混合编程 混合编程是指在C/C++程序中调用其他语言编写的模块,例如Python、Java等。在C/C++中实现混合编程有多种方法,本文将详细讲解其中的两种常见方法。 方法1:使用C++的Extern-C机制 C++支持Extern-C机制,能够将C++代码转化为类似于C的代码,从而实现C/C++混合编程。具体操作步骤如下: 使用C++编写…

    C 2023年5月23日
    00
  • 如何处理json中不带双引号的key的问题

    如果遇到JSON中不带双引号的key时,通常会遇到解析器无法将JSON字符串解析成JSON对象的问题。 下面是处理这个问题的几种方法: 1.将JSON字符串中的单引号替换成双引号 可以通过将JSON字符串中的单引号替换成双引号来解决这个问题。这可以使用正则表达式和字符串的replace()方法来实现。 以下是一个示例: const jsonObj = JSO…

    C 2023年5月23日
    00
  • C++中的常对象与常对象成员详解

    C++中的常对象与常对象成员详解 在C++中存在常对象和常对象成员,它们都有一个共同点:都不允许在对象的生命周期内被修改。下面我们详细讲解常对象和常对象成员的定义、声明、初始化及其特点。 常对象 定义 常对象是指一个对象在它被创建后就无法被修改。在C++中,我们可以通过在对象类型前面加上const关键字来定义常对象。例如: const int a = 10;…

    C 2023年5月22日
    00
  • visual studio 2010怎么创建c项目?

    Visual Studio 2010是一个强大的集成开发环境 (IDE),可用于创建各种类型的项目,包括C++项目。下面是创建C++项目的详细步骤: 打开Visual Studio 2010,点击“文件”菜单,选择“新建”-> “项目”。 在“新建项目”对话框中,选择“Win32控制台应用程序”模板,命名项目名称,并选择项目保存的位置。如果需要在项目中…

    C 2023年5月23日
    00
  • 荣耀畅玩8c手机如何分屏?荣耀畅玩8c分屏教程

    下面是荣耀畅玩8c手机如何分屏的完整攻略: 一、什么是分屏功能 分屏功能是荣耀畅玩8c手机的一项特色功能,它可以让你同时在同一个屏幕上,使用两个应用程序。 二、如何开启分屏功能 荣耀畅玩8c手机的分屏功能很容易使用,具体步骤如下: 先打开一个想要使用的应用程序,例如微信。 按住主屏幕底部左侧的“返回键不放”,直到屏幕出现一个小框框。 放开“返回键”后,屏幕就…

    C 2023年5月23日
    00
合作推广
合作推广
分享本页
返回顶部