ARM - AArch64 - 通用寄存器

2023-11-30 22:15
文章标签 arm 通用寄存器 aarch64

本文主要是介绍ARM - AArch64 - 通用寄存器,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

说明

  • 在深入一点了解了系统调用以及非安全world(REE)/安全world(TEE)切换时参数传递和结果返回的实现原理(通过通用寄存器实现),对通用寄存器的使用有了一个全新的认识,对知识做个总结。

简介

  • Arm AArch64状态下提供了31个64位通用寄存器:X0 ~ X30。

通用体现

  1. 不同于特殊寄存器(每一bit可能都有特殊作用),通用寄存器本身没有任何作用(就是一个64位存储器),其作用是由使用体现。
  2. 任意时间任意环境(任意特权等级,任意安全等级,用户态/内核态)都可以使用这些通用寄存器,没有任何访问限制。
    1. 应用层调用系统调用(应用态和内核态切换),参数传递和结果返回等都是使用通用寄存器实现。
    2. 应用层程序执行,函数调用时参数传递,也是使用通用寄存器实现。
    3. REE与TEE通信,需要做非安全world和安全world切换,异常等级切换等也是使用通用寄存器传递参数和运行结果。
    4. 任何异常等级中函数执行也是使用这些通用寄存器,切换异常等级也不会丢失。
  • 重点:通用寄存器是参数传递,返回结果等一些通用行为使用的寄存器,在任何场景,环境下(用户态/内核态切换,安全world/非安全world切换)都是一样,没有其它寄存器。

32位形态

  • X0 ~ X30是64位寄存器,也可以作为32位寄存器使用,其32位形态(W0 ~ W30)取自相应64位寄存器(X0 ~ X30)的低32位,例如:W0映射到X0的低32位,W1映射到X1的低32位。
  • 读写其32位形态行为如下:
  1. 读取,从32位寄存器(W0-W30)读取时,忽略相应64位寄存器(X0-X30)高32位,并保持其它不变。
  2. 写入,将数据写入32位寄存器(W0-W30)时,会将其对应的64位寄存器(X0-X30)的高32位设置为零,例如:将0xFFFFFFFF写入W0会将X0设置为0x00000000FFFFFFFF。

用途

  • 通用寄存器的用途更多的是一种使用规范,并没有什么强制限制。
  • 不同使用场景会有些细微区别。

规范

  • 根据用途,通用寄存器可以分为四组。

x0 ~ x7

  1. 传递参数
  • 应用层函数调用,传递子函数的参数,超出的参数用堆栈传递。
  • 应用层调用系统调用,传递系统调用的参数,系统调用只支持6个参数,因此只用到了x0 ~ x5。
  • REE与TEE通信,SMC请求使用x0 ~ x7 传递参数。
  1. 传递返回值
  • 应用层调用系统调用,函数调用,64位的返回结果保存在x0中。
  • REE与TEE通信,ERET使用x0 ~ x3 传递TEE运行结果。
  1. 临时存储器
  • 在函数中也可以用作临时寄存器,可以保存中间值或调用者的寄存器变量。

X9-X15:调用者寄存器

  • 网上描述:如果调用者需要在调用另一个函数时保留一些寄存器中的任何值,则调用者必须将受影响的寄存器保存在自己的堆栈帧中。 也可以修改子例程,而不需要在返回调用函数时保存值到堆栈和从堆栈中恢复它们。
  • 后续体会较深时,再修正。

X19-X29:被调用寄存器

  • 网上描述:这些寄存器保存在被调用者内部。 只要在返回前保存并恢复,就可以在被调用的子程序中修改。
  • 后续体会较深时,再修正。

X8, X16-X18, X29, X30:特殊目的寄存器

  • X8 是间接结果寄存器。用于传递间接结果的地址位置,例如,函数返回大型结构的位置。
  • x8 在系统调用(syscall)中用于传递系统调用编号。
  • 网上描述:X16 和 X17 分别是 IP0 和 IP1,临时寄存器(intra-procedure-call )可以通过veneers或者类似代码使用,或者作为子程序调用之间的中间值的临时寄存器。它们可以被函数破坏。veneers代码是链接器自动插入的一小段代码,例如当分支(跳转)目标超出分支指令(支持的)范围时。
  • X18 是平台寄存器,保留供平台 ABI 使用。这是平台上的一个附加临时寄存器,没有为其分配特殊含义。
  • X29 是 Frame Pointer 寄存器,指向当前方法栈的底部。用于连接栈帧,使用时必须保存。
  • X30 是链接寄存器,这个寄存器会记录着当前方法的调用方地址 ,即当前方法调用完成时应该返回的位置。我们进行函数调用的时候,会用X30记录当前调用地址,等调用函数执行完毕,会从X30取出地址进行返回。我们遇到 Crash 要获取方法堆栈,其本质就是不断的向上递归每一个 x30 寄存器的记录状态(也就是栈上 X30 寄存器的内容) 来找到上层调用方。
  • 后续体会较深时,再修正。

实际使用

  • 系统调用实现
// 标准C库(musl)syscall 实现  
#define __asm_syscall(...) do { \__asm__ __volatile__ ( "svc 0" \: "=r"(x0) : __VA_ARGS__ : "memory", "cc"); \return x0; \   //使用 x0传递返回值} while (0)static inline long __syscall0(long n)
{   register long x8 __asm__("x8") = n; //使用 x8传递系统编译编号register long x0 __asm__("x0");__asm_syscall("r"(x8));
}
...
static inline long __syscall6(long n, long a, long b, long c, long d, long e, long f)
{register long x8 __asm__("x8") = n; register long x0 __asm__("x0") = a; //使用x0 ~ x5传递参数register long x1 __asm__("x1") = b;register long x2 __asm__("x2") = c;register long x3 __asm__("x3") = d;register long x4 __asm__("x4") = e;register long x5 __asm__("x5") = f;__asm_syscall("r"(x8), "0"(x0), "r"(x1), "r"(x2), "r"(x3), "r"(x4), "r"(x5));
}

这篇关于ARM - AArch64 - 通用寄存器的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/438753

相关文章

bash: arm-linux-gcc: No such file or directory

ubuntu出故障重装了系统,一直用着的gcc使用不了,提示bash: arm-linux-gcc: No such file or directorywhich找到的命令所在的目录 在google上翻了一阵发现此类问题的帖子不多,后来在Freescale的的LTIB环境配置文档中发现有这么一段:     # Packages required for 64-bit Ubuntu

编译linux内核出现 arm-eabi-gcc: error: : No such file or directory

external/e2fsprogs/lib/ext2fs/tdb.c:673:29: warning: comparison between : In function 'max2165_set_params': -。。。。。。。。。。。。。。。。。。 。。。。。。。。。。。。。 。。。。。。。。 host asm: libdvm <= dalvik/vm/mterp/out/Inte

Cortex-A7:ARM官方推荐的嵌套中断实现机制

0 参考资料 ARM Cortex-A(armV7)编程手册V4.0.pdf ARM体系结构与编程第2版 1 前言 Cortex-M系列内核MCU中断硬件原生支持嵌套中断,开发者不需要为了实现嵌套中断而进行额外的工作。但在Cortex-A7中,硬件原生是不支持嵌套中断的,这从Cortex-A7中断向量表中仅为外部中断设置了一个中断向量可以看出。本文介绍ARM官方推荐使用的嵌套中断实现机

ARM 虚拟化介绍

0.目录 文章目录 0.目录1.概述 1.1 Before you begin 2.虚拟化介绍 2.1 虚拟化为什么重要2.2 hypervisors的两种类型2.3 全虚拟化和半虚拟化2.4 虚拟机和虚拟CPUs 3.AArch64中的虚拟化4.stage 2 转换 4.1 什么是stage 2 转换4.2 VMIDs4.3 VMID vs ASID4.4 属性整合和覆盖4.5模拟

QEMU用户模式测试AARCH64程序

QEMU的两种模式 QEMU(快速模拟器)是一个开源的机器模拟器和虚拟化器,它能够模拟多种处理器架构,并且可以在不同平台上运行。QEMU 支持两种模式:用户模式和系统模式。 用户模式(User Mode): 用户模式下的 QEMU 仅模拟用户空间的二进制执行环境,不模拟底层硬件。这种模式下,QEMU 可以运行不同架构编译的二进制程序,而不需要这些程序与宿主机的架构相匹配。用户模式通常用于测试和

SylixOS ARM平台下内存对齐访问

1.内存对齐 1.1     内存对齐概要 现代计算机中内存空间都是按照byte划分的,从理论上讲对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定变量的时候经常在特定的内存地址访问,这就需要各类型数据按照一定的规则在空间上排列,而不是顺序的一个接一个的排放,这就是对齐。 1.2     内存对齐作用和原因 各个硬件平台对存储空间的处理上有很大的不同。一些平

ubuntu22.04 qemu 安装windows on arm虚拟机

ubuntu22.04 qemu 安装windows on arm虚拟机 iso: https://uupdump.net/ https://massgrave.dev/windows_arm_links vivo driver: https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/archive-virtio/

arm linux lua移植

lua: lua home 1.下载lua源码 lua下载 lua-5.3.4.tar.gz 2.解压: tar xvf lua-5.3.4.tar.gz 3.修改makefile and luaconf.h $修改 lua-5.3.4/Makefile #INSTALL_TOP= /usr/local INSTALL_TOP= $(shell pwd)/out #修改安装目录(当前目录/o

正点原子阿尔法ARM开发板-IMX6ULL(二)——介绍情况以及汇编

文章目录 一、裸机开发(21个)二、嵌入式Linux驱动例程三、汇编3.1 处理器内部数据传输指令3.2 存储器访问指令3.3 压栈和出栈指令3.4 跳转指令3.5 算术运算指令3.6 逻辑运算指令 一、裸机开发(21个) 二、嵌入式Linux驱动例程 三、汇编 我们在进行嵌入式 Linux 开发的时候是绝对要掌握基本的 ARM 汇编,因为 Cortex-A 芯片一

ARM架构(五)——MMU①

1.MMU基础 1.1 为什么要用MMU,为什么要用虚拟地址? MMU的作用,主要是完成地址的翻译,即虚拟地址到物理地址的转换,无论是main-memory地址(DDR地址),还是IO地址(设备device地址),在开启了MMU的系统中,CPU发起的指令读取、数据读写都是虚拟地址,在ARM Core内部,会先经过MMU将该虚拟地址自动转换成物理地址,然后在将物理地址发送到AXI总线上,完成真正