ARM64汇编0B - 函数调用约定

建议先看《CSAPP》的3.7节,讲的很细。我们这里就直接看例子来分析了。

例子

static int func(int a, int b, int c, int d, int e, int f, int g, int h, int i)
{printf("%s\n", "add all");int x = a + b;return a + b + c + d + e + f + g + h + i;
}int main()
{getchar();int result = func(1, 2, 3, 4, 5, 6, 7, 8, 9);printf("result = %d\n", result);return 0;
}

上面的程序,我们写了一个 func 的调用,主要是观察其参数传递时,寄存器的使用以及栈的变化情况。

在ARM64体系结构中,栈是从高地址往低地址生长。栈在函数调用过程中起到非常重要的作用,包括存储函数使用的局部变量、传递参数等。在函数调用过程中,栈是逐步生成的。为单个函数分配的栈空间,即从该函数栈底(高地址)到栈顶(低地址)这段空间称为栈帧(Stack Frame)。

ARM64在函数参数传递时,参数1~参数8 分别保存到 X0~X7 寄存器中 ,剩下的参数从右往左依次入栈,被调用者实现栈平衡,返回值存放在 X0 中。

ARM在参数传递时,参数1~参数4 分别保存到 R0~R3 寄存器中 ,剩下的参数从右往左依次入栈,被调用者实现栈平衡,返回值存放在 R0 中。

我们看下上面程序的反汇编代码,有个地方需要注意,为了观察最原始的汇编代码需要在Applicataion.mk 里面添加一个选项,否则编译器会优化一些逻辑:

APP_OPTIM := debug
.text:0000000000000784 A8 03 5F B8                   LDUR            W8, [X29,#var_10]
.text:0000000000000788 E0 03 08 2A                   MOV             W0, W8                  ; a
.text:000000000000078C A1 C3 5E B8                   LDUR            W1, [X29,#var_14]       ; b
.text:0000000000000790 A2 83 5E B8                   LDUR            W2, [X29,#var_18]       ; c
.text:0000000000000794 A3 43 5E B8                   LDUR            W3, [X29,#var_1C]       ; d
.text:0000000000000798 E4 23 40 B9                   LDR             W4, [SP,#0x40+e]        ; e
.text:000000000000079C E5 1F 40 B9                   LDR             W5, [SP,#0x40+f]        ; f
.text:00000000000007A0 E6 1B 40 B9                   LDR             W6, [SP,#0x40+g]        ; g
.text:00000000000007A4 E7 17 40 B9                   LDR             W7, [SP,#0x40+h]        ; h
.text:00000000000007A8 EA 03 00 91                   MOV             X10, SP
.text:00000000000007AC E9 13 40 B9                   LDR             W9, [SP,#0x40+var_30]
.text:00000000000007B0 49 01 00 B9                   STR             W9, [X10,#0x40+i]       ; i
.text:00000000000007B4 0A 00 00 94                   BL              func

可以看到 a b c d e f g h,这8个参数是存放到了 W0 - W7 中,W 是 X 的32 位形式。

对于参数 i 的处理分3步:

MOV             X10, SP                    ;将sp的值给X10
LDR             W9, [SP,#0x40+var_30]      ;将9赋值给W9
STR             W9, [X10,#0x40+i]          ;将9储存到 sp+offset 中

是先将栈地址赋值给了 X10,然后将 i 的值存放到 W9 指向的地址里面,结合起来理解就是将 i 的值放到了栈里面。

我们动态的调试一下,观察栈变化:

前面的X0到X7的寄存器变化是符合预期的。

继续往下看,断点走到BL处,发现栈变化:

发现,将 9 的值储存到了 sp 的位置,偏移量为0。说明 [X10,#0x40+i] 计算出来的值就是 [X10],我们可以在这里按下Q键,看真实的汇编:

继续往下看,看跳转到 func 函数里面后栈的变化情况。一直走到 func 的 ret 指令,看栈的内容:

0000007FE24A0AE8  0000000900000003  
0000007FE24A0AF0  0000000700000008  
0000007FE24A0AF8  0000000500000006  
0000007FE24A0B00  0000000300000004  
0000007FE24A0B08  0000000100000002  
0000007FE24A0B10  0000007FE24A0B60  [stack]:0000007FE24A0B60
0000007FE24A0B18  000000632CC977B8  main+A4
0000007FE24A0B20  0000000000000009

可以看到,栈底首先储存的是第9个参数。

然后是返回地址,就是函数执行完之后需要执行的下一条指令的地址。

然后接着是栈指针,这个栈指针是 main 函数的栈地址,因为func函数执行完之后,需要将栈指针给还原,mian才好继续执行。

然后接着是参数,这是因为函数的逻辑可能需要使用到 X0 到 X7寄存器。所以先将寄存器的值储存到栈中,方便后续获取。

最后是局部变量,它的值也是放到了栈中。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/30634.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java环境变量配置以及“‘javac‘ 不是内部或外部命令”问题的解决方法(2024年6月姆级最新)

😀前言 有很多小伙伴提问这个所以就单独出一个解决教程 java环境变量配置以及“‘javac’ 不是内部或外部命令”问题的解决方法(2024年6月姆级最新) 安装的话可以参考这个 java 安装和环境配置(2024-4月保姆级最新版) 🏠个人主页…

工业园安全生产新保障:广东地区加强可燃气体报警器校准检测

广东,作为我国经济的重要引擎,拥有众多工业园区。 这些工业园区中,涉及化工、制药、机械制造等多个领域,每天都会产生和使用大量的可燃气体。因此,可燃气体报警器的安装与校准检测,对于保障工业园区的安全…

Python 绘制圆欠采样时的数学图形

Python 绘制圆欠采样时的数学图形 正文end_radian 190end_radian 180end_radian 170end_radian 130end_radian 120 正文 今天在绘制圆形的时候遇到了意外,发现了一个有意思的现象,这里特来记录一下。 end_radian 190 import numpy as np import…

【MySQL统计函数count详解】

MySQL统计函数count详解 1. count()概述2. count(1)和count(*)和count(列名)的区别3. count(*)的实现方式 1. count()概述 count() 是一个聚合函数,返回指定匹配条件的行数。开发中常用来统计表中数据,全部数据,不为null数据,或…

【SpringCloud】负载均衡(Spring Cloud LoadBalancer)

负载均衡 当服务流量增大时,通常会采用增加机器的方式进行扩容。负载均衡就是用来在多个机器或者其他资源中,按照一定的规则合理分配负载。其中的实现可以分成客户端负载均衡和服务端负载均衡。 服务端负载均衡 在服务端进行负载均衡的算法分配。 比…

数据丢失?别怕,EasyRecovery来帮忙!

🌟 数据丢失?别怕,EasyRecovery来帮忙! 嘿,亲爱的的朋友们!👋今天我要和大家分享一款超棒的数据恢复软件——EasyRecovery!🎉你是否曾经遇到过不小心删除了重要文件、照片…

zip文件上传到linux服务器文件大小发生变化

在传一个文件到服务器的时候,第一次传完看见大小不一样(服务器中du命令查看大小796596MB)就重传了一下,还是大小不一样,就查了下。 查了下有以下原因: 文件系统的不同: 原因:不同的…

windows 系统根据端口查找进程,杀死进程

在启动项目时,往往设置的端口被占用,这时需要杀死端口所占用的进程,然后再重启项目。 netstat -ano | findstr :8085 taskkill /F /PID 25184 杀死进程后,再执行命令 netstat -ano | findstr :8085 进行查看端口占用情况

STM32多功能交通灯系统:从原理到实现

一、功能说明 本交通灯系统采用先进的stm32f103c8t6微处理器为核心控制单元。系统设置东南西北四个方向各配置两位数码管,用以精准展示5至99秒的时间范围,并且允许用户根据实际需求进行灵活调整。 在信号灯配置方面,每个方向均配备左转、直…

SYD881X读取GATT VALUE的长度

SYD881X读取GATT VALUE的长度 现在具体遇到这样一个需要,机器生产后要更新profile,这个只能够通过升级4K来做,但是需要知道profile是否改变了,这个就要知道profile是否改变来决定是否要升级,这里的做法是增加一个函数&…

肩背筋膜炎怎么治疗最有效

肩背筋膜炎是一种常见的肌肉骨骼疾病,其症状主要包括:肩背区域疼痛:由于筋膜组织受到损伤,肩背部位会出现明显的疼痛,疼痛可能会放射到周围的其他部位,严重时会影响睡眠和休息。肌肉紧张和僵硬:…

嵌入式数据库_2.嵌入式数据库的一般架构

嵌入式数据库的架构与应用对象紧密相关,其架构是以内存、文件和网络等三种方式为主。 1.基于内存的数据库系统 基于内存的数据库系统中比较典型的产品是每个McObject公司的eXtremeDB嵌入式数据库,2013年3月推出5.0版,它采用内存数据结构&…

智能座舱中的HUD介绍

HUD(Head Up Display,抬头显示系统)是将车速、油耗、胎压等行车重要信息投影到前方挡风玻璃上的一套显示系统。HUD 最早应用在战斗机上,旨在降低飞行员低头查看仪表的频率,使得飞行员能在保证正常驾驶的同时&#xff0…

2002-2022年各省人口总抚养比数据(人口抽样调查)

2002-2022年各省人口总抚养比数据(人口抽样调查) 1、时间:2002-2022年 2、指标:总抚养比 3、来源:国家统计局、统计年鉴 4、范围:31省, 5、缺失情况:无缺失,其中201…

Git 和 TortoiseGit 安装和配置(图文详解)

使用git,需要在Windows上需要安装两个软件:1)Git 2)TortoiseGit 注意:tortoiseGit是在安装了Git的基础上运行的,所以需要先安装Git,后安装运行tortoiseGit。 因为,运行TortoiseGi…

Web3新视野:Lumoz节点的潜力与收益解读

摘要:低估值、高回报、无条件退款80%...... Lumoz正通过其 zkVerifier 节点销售活动,引领一场ZK计算革命。 长期以来,加密市场以其独特的波动性和增长潜力,持续吸引着全球投资者的目光。而历史数据表明,市场往往在一年…

六西格玛目标设定的时候需要考虑哪些因素?

在追求企业卓越绩效的道路上,六西格玛管理方法论以其严谨的数据驱动和持续改进的理念,成为众多企业的首选工具。然而,要想真正发挥六西格玛的潜力,合理而精准的目标设定至关重要。那么,六西格玛目标设定的时候需要考虑…

电商API接口详述:涵盖订单、库存等多功能接口介绍

电商商家自研管理系统,线下ERP系统或WMS系统想要接入电商平台订单打单发货,通过点三电商API可以一键对接多个电商平台,帮助商家、ERP/WMS服务商快速开发电商模块,实现电商业务管理功能,那么点三电商API接口有哪些可用接…

Stranger Lands - StampIT

作为StampIT!Collection的一部分,Stranger Lands包含30个高质量纹理,具有惊人的4K分辨率。这些高度图纹理可以用作Unity地形工具的画笔,以便在Unity地形上绘制特征。或者您可以在Atlas、Gaia、Map Magic 2、Vista等其他资源中使用这些高度图纹理。 该资源包含高度图和笔刷预…

Java多线程+线程池图文实例操作(源码自取)

目录 线程相关概念 并发 并行 继承Thread类 实现Runnable接口 实现Callable接口 使用ExecutorService 和线程池 多线程卖手机 非同步 同步机制卖手机 锁方法 锁代码块 ​编辑锁静态方法 锁静态代码块 线程常用方法 用户线程和守护线程 线程状态 线程池 自定…