当前位置: 首页 > news >正文

RISCV学习(1)基本模型认识

笔者来聊聊ARM的函数的调用规则

1、ARM函数调用规则介绍

首先介绍几个术语,

  • AAPCS:Procedure Call Standard for the ARM Architecture
  • APCS:ARM Procedure Call Standard
  • TPCS:Thumb Procedure Call Standard
  • ATPCS:ARM-Thumb Procedure Call Standard
  • ABI:Application Binary Interface
  • EABI:Embedded Application Binary Interface

前三个基本就是ARM 架构的程序调用标准(包括ARM指令以及thumb指令),最后两个是程序二进制接口,描述是汇编下面寄存器名使用、函数调用、压栈、参数传递以及程序返回等一系列接口标准。

比如x86与arm架构的ABI 就不兼容,寄存器都不一样,肯定就是无法互相使用,包括最近比较火热的RISC-V架构。

2、ARM32/64 函数调用规则

ARM架构下面分为32位以及64位的程序,其标准有些不同以及扩展,可分开来讲。

2.1、ARM

  • 机器寄存器
    对于ARM以及thumb指令集来说,总有16个寄存器使用,不管大小写,在汇编语言里面都是可以识别的,一般来说大写的有特殊用途,详情见下文。
    • R0-R3 作为函数参数传递以及返回值使用,也可以在程序中保存立即数。
    • R12 (IP)链接器使用的暂存器
    • R9 平台寄存器,ARM不推荐使用,避免平台依赖
    • R4-R8,R10,R11 暂存器
    • R11 作为栈指针,指向程序调用中开辟空间的栈底,可用来栈回溯,具体可以参考ARMARM学习(1) 寄存器的理解 ===》FP、SP、LR寄存器。
    • R13 SP 栈指针
    • R14 LR 链接寄存器
    • R15 PC 程序计数器
    • CPSR 状态寄存器 详情介绍见ARM学习(2) 寄存器的理解 ===》通用寄存器及状态寄存器。
    • cp15 协处理 监控通用寄存器的使用
      在这里插入图片描述
  • 程序处理、内存以及栈
    一个程序的内存通常会划分为几部分:Code、read-only static data、writeable static data、heap and stack,Code段里面会包括read-only static data,DATA段会包括初始化好的全局变量,BSS包括堆栈以及未初始化和初始化为0的全局变量
    • stack 临时存储变量以及传递额外的参数(程序调用时寄存器数量不足),
    • 栈有范围限制,Limit < SP < Base
    • 其次必须4 byte对齐,
    • 程序必须访问栈的部分范围内区域(SP ,base-1),不能访问之外的区域,
      在这里插入图片描述
  • 子程序调用
    • BL指令会跳到目标程序,并且修改LR为当前PC的按顺序下一条指令地址,指的是没跳转之前的PC的下一条。
    • 需要注意修改LR最低位表示当前为什么状态,,0:是arm状态,无需修改(因为地址都是word 2Byte对齐的),1:是thumb状态,需要修改,
      在这里插入图片描述
      可以看到R14以及PC的值都是奇数,代表是thumb指令。
      在这里插入图片描述
      在这里插入图片描述
      R15(PC):0x0801247E 位于 DMA_GetFlagStatus,
      R14:0x08014ECB 位于 UART1_SentMsgL,保存了其返回的地址。
  • 返回值

    • R0:返回值是D-Word(32 bit),或者是单精度浮点型float,
    • R0-R1:返回值是Q-Word(64 bit),或者双精度浮点型double
    • R0-R3:返回值是128bit的向量
      在这里插入图片描述
      调用GetSysTime之后,r0则获取到值,然后r1计算好之后,则cmp进行比较r0,r1.
  • 参数传递

    • R0-R3 和栈进行传递
    • 参数少的函数,只用寄存器就可以了,减少访问内存带来的负载
    • 优先寄存器,然后栈,寄存器从小到大,栈地址从小到大。
      1、函数声明:void OLED_DrawBMP_test(unsigned char x0, unsigned char y0,unsigned char x1, unsigned char y1,unsigned char BMP[],unsigned char state1,unsigned char state2);
      2、共用7个参数:x0,y0,x1,y1,BMP[],state1,state2
      3、前四个参数都分别存储在r0-r3,
      4、后面三个参数存储在栈中,strd r7,r6,[r13] 以及str r6,[r13,#0x8] ,前面指令存储r7 r6 两个参数,后面地址偏移8之后,又存储一个参数,总计三个参数,存储顺序依次都是参数从左向右去存储。
      5、不符合__cdecl、__stdcall、__fastcall这三种调用标准。
      在这里插入图片描述
  • 内部联合工作(ARM与Thumb指令)

    • 子程序调用和程序返回支持两张状态切换。bx或者blx都可以切换状态。

2.2、ARM64

参考文档

1、ARM Procedure Call Standard
2、Procedure Call Standard for the ARM 64-bit Architecture (AArch64)

http://www.lryc.cn/news/24211.html

相关文章:

  • 【java代码审计】命令注入
  • 速锐得适配北汽EX系列电动汽车CAN总线应用于公务分时租赁
  • 已解决ERROR: Failed building wheel for opencv-python-headless
  • 每日获取安全资讯的网站,国内外共120个
  • HUN工训中心:开关电路和按键信号抖动
  • WordPress 主题 SEO 标题相关函数和过滤器教程wp_get_document_title()
  • Qt 事件机制
  • 【Python】Numpy--np.linalg.eig()求对称矩阵的特征值和特征向量
  • 医疗床头卡(WIFI方案)
  • [YOLO] yolo博客笔记汇总(自用
  • Linux 常用 API 函数
  • 【转载】bootstrap自定义样式-bootstrap侧边导航栏的实现
  • 奇瑞x华为纯电智选车来了,新版ADS成本将大幅下降
  • 机器学习的特征归一化Normalization
  • 程序员看过都说好的资源网站,看看你都用过哪些?
  • Win11的两个实用技巧系列之设置系统还原点的方法、安全启动状态开启方法
  • 【Linux】项目的自动化构建-make/makefile
  • 【Redis学习2】Redis常用数据结构与应用场景
  • 踩了大坑:https 证书访问错乱
  • 大数据技术之Hive(四)分区表和分桶表、文件格式和压缩
  • 环形缓冲区(c语言)
  • 创建自助服务知识库的指南
  • 分层测试(1)分层测试是什么?【必备】
  • 开源ZYNQ AD9361软件无线电平台
  • 第四阶段-12关于Spring Security框架,RBAC,密码加密原则
  • JPA——Date拓展之Calendar
  • 一文吃透 Spring 中的 AOP 编程
  • Apple主推的智能家居是什么、怎么用?一篇文章带你从零完全入门 HomeKit
  • SpringCloud系列知识快速复习 -- part 1(SpringCloud基础知识,Docker,RabbitMQ)
  • 2023上半年北京/上海/广州/深圳NPDP产品经理认证报名