汇编基础(2) -- ARM64

2023-09-20 17:43:49

简介

ARM架构中,ARM64(也称为AArch64)是一种64位处理器架构,它是ARMv8指令集的一部分。与之前的32位ARM架构相比,ARM64提供了更大的寄存器容量、更广阔的地址空间和更高的计算能力。

64位版本的指令集和32位版本的指令集有一些区别,这些区别主要涉及到以下几个方面:

  • 寄存器:ARM64架构提供了31个通用寄存器,每个寄存器的容量为64位。相比之下,32位ARM架构只有16个通用寄存器,每个寄存器的容量为32位。

  • 操作数大小:在ARM64架构中,所有数据都是以64位的形式进行处理。相比之下,32位ARM架构只能处理32位的整数和单精度浮点数。

  • 内存地址空间:在ARM64架构中,虚拟地址空间最大可达256TB,可以同时支持多达4亿个进程。相比之下,32位ARM架构只支持最大4GB的虚拟地址空间,并且最多只能支持4096个进程。

  • 执行速度:由于ARM64架构的寄存器容量更大、操作数更大,所以在大多数情况下,ARM64指令集的执行速度比32位ARM指令集更快。

  • 兼容性:ARM64架构与32位ARM架构不兼容,因此32位的应用程序不能在ARM64架构的处理器上直接运行。

寄存器

寄存器说明
x0-x7通用寄存器,用于函数参数传递和返回值存储
x8通用寄存器,可用作附加参数传递
x9-x15通用寄存器,用于临时数据存储
x16通用寄存器,可用作线程/进程本地数据存储区域指针
x17通用寄存器,可用作异常链接寄存器
x18通用寄存器,可用作平台相关寄存器
x19-x28通用寄存器,用于临时数据存储
x29 (fp)帧指针寄存器,用于保存当前函数的帧指针
x30 (lr)链接寄存器,用于保存返回地址
sp栈指针寄存器,指向当前栈顶位置
pc程序计数器寄存器,存储下一条要执行的指令的地址
cpsr当前程序状态寄存器,保存处理器的当前状态信息,如条件标志位、中断使能位、处理模式等
nzcv零、负、进位和溢出条件标志位,记录上一条指令结果的状态
f0-f31浮点寄存器,用于浮点运算
v0-v31矢量寄存器,用于SIMD(单指令多数据)操作
w032位宽的低位部分,对应于x0寄存器
s016位宽的低位部分,对应于x0寄存器的低16位
b08位宽的最低字节部分,对应于x0寄存器的最低字节

指令

指令类型示例指令说明
数据传输LDR X0, [X1]从内存中加载数据到寄存器
STR X0, [X1]将寄存器中的数据存储到内存
算术运算ADD X0, X1, X2将两个寄存器中的值相加
SUB X0, X1, X2将两个寄存器中的值相减
逻辑运算AND X0, X1, X2将两个寄存器中的值进行按位与
ORR X0, X1, X2将两个寄存器中的值进行按位或
控制流B label分支到标签处执行
BL label分支并且保留返回地址
CMP X0, X1比较两个寄存器中的值
BEQ label如果上一次比较结果为相等,则分支到标签处执行
B label无条件跳转到标签处执行
BL label分支与链接 跳转到标签处执行,并保存返回地址
BR Xn无条件跳转到寄存器Xn中存储的地址
B.cond label根据特定条件进行跳转
BLR Xn无条件跳转到寄存器Xn中存储的地址,并保存返回地址
BR Xn无条件跳转到寄存器Xn中存储的地址,并恢复返回地址及上下文
BLR Xn跳转到寄存器Xn中存储的地址,并保存返回地址及上下文
乘法和除法MUL X0, X1, X2将两个寄存器中的值相乘
SDIV X0, X1, X2将两个寄存器中的值相除
浮点运算FADD D0, D1, D2将两个浮点寄存器中的值相加
FSUB D0, D1, D2将两个浮点寄存器中的值相减
FMUL D0, D1, D2将两个浮点寄存器中的值相乘
FDIV D0, D1, D2将两个浮点寄存器中的值相除
压栈STP X0, X1, [SP, #-16]!将两个寄存器的值压入栈中
STR X0, [SP, #-8]!将一个寄存器的值压入栈中
出栈LDP X0, X1, [SP], #16从栈中弹出两个寄存器的值
LDR X0, [SP], #8从栈中弹出一个寄存器的值
设置栈指针MOV SP, X0将指定寄存器的值设置为栈指针
获取栈指针MOV X0, SP将栈指针的值保存到指定寄存器

实例分析

  • 包含if语法的函数:
int ifFunction(int x, int y) {
    int result;
    if (x > y) {
        result = x + y;
    } else {
        result = x - y;
    }
    return result;
}

ifFunction:
    cmp x0, x1      // 比较 x 和 y
    ble else_label  // 如果 x <= y,跳转到 else_label 标签处
    add x0, x0, x1  // 如果 x > y,执行 x + y
    ret             // 返回结果
else_label:
    sub x0, x0, x1  // 如果 x <= y,执行 x - y
    ret             // 返回结果

  • 包含for语法的函数:
int forFunction(int n) {
    int sum = 0;
    for (int i = 1; i <= n; i++) {
        sum += i;
    }
    return sum;
}

forFunction:
    mov w1, 1       // 将 1 赋值给寄存器 w1,作为循环计数器 i 的初始值
    mov w0, 0       // 将 0 赋值给寄存器 w0,作为累加和 sum 的初始值
loop:
    add w0, w0, w1  // 累加计数器 i 的值到累加和 sum
    add w1, w1, 1   // 计数器 i 自增 1
    cmp w1, x0      // 比较计数器 i 和 n 的值
    ble loop        // 如果 i <= n,跳转到 loop 标签处继续循环
    ret             // 返回累加和 sum

  • 包含switch语法的函数:
int switchFunction(int x) {
    int result;
    switch (x) {
        case 1:
            result = 10;
            break;
        case 2:
            result = 20;
            break;
        case 3:
            result = 30;
            break;
        default:
            result = -1;
    }
    return result;
}

switchFunction:
    cmp w0, 1       // 比较寄存器 w0(x)的值与每个 case 的值
    b.eq case_1     // 如果相等,跳转到 case_1 标签处
    cmp w0, 2
    b.eq case_2
    cmp w0, 3
    b.eq case_3
    mov w0, -1      // 默认情况下,将 -1 赋值给寄存器 w0(result)
    ret
case_1:
    mov w0, 10      // 如果 x == 1,将 10 赋值给寄存器 w0(result)
    ret
case_2:
    mov w0, 20      // 如果 x == 2,将 20 赋值给寄存器 w0(result)
    ret
case_3:
    mov w0, 30      // 如果 x == 3,将 30 赋值给寄存器 w0(result)
    ret

参考

更多推荐

Liunx(Ubuntu20)常用指令

-rwxr-xr-x,在Linux系统中权限是区分用户的,即用户、组用户、其他用户,第一位表示文件的类型,-代表文件,d代表目录,其他每个用户占三个字符用户、组用户、其他用户都是rwx形式,其中r表示读、w表示写、x表示可执行,-表示没有权限,拿用户组举例,r只能出现在第一个位置、w只能出现在第二个位置、x只能出现在第

在 CentOS 上安装 Docker Engine

文章目录在CentOS上安装DockerEngine先决条件操作系统要求卸载旧版本安装方法使用rpm存储库安装设置存储库安装DockerEngine安装最新版本安装指定版本以非root用户身份管理Docker配置Docker以使用systemd启动参考官方文档:https://docs.docker.com/engin

阿里云服务器价格表,轻量和服务器最新活动价格表汇总

租用阿里云服务器怎么收费?阿里云服务器配置不同一年价格也不同,阿里云2核2G3M带宽108元一年、2核4G4M带宽297.98元12个月,云服务器u1公网带宽可选1M到5M,系统盘为ESSD云盘40GB起,CPU内存配置可选2核2G、2核4G、4核8G、8核16G等配置,还有ECS计算型c7、通用型g7和内存型r7多C

【SLAM】前端-视觉里程计之对极几何

文章目录【SLAM】前端-视觉里程计之对极几何1.对极几何2.本质矩阵及其求解3.单应矩阵及其求解3.三角测量4.思考4.1本质矩阵的自由度为多少4.2直接法求本质矩阵的过程涉及求解齐次线性方程,而对于齐次线性方程的解,要么只有零解,要么有无穷多个解,这里取哪一个解呢5.附录5.1相机成像模型【SLAM】前端-视觉里程

接口测试——接口协议抓包分析与mock_L1

目录:接口测试价值与体系常见的接口协议接口测试用例设计postman基础使用postman实战练习1.接口测试价值与体系接口测试概念接口:不同的系统之间相互连接的部分,是一个传递数据的通道接口测试:检查数据的交换、传递和控制管理过程接口测试的价值传统的测试方法成本急剧上升测试效率下降分层测试体系越往上,发现Bug的时间

CSS 布局 (三) 浮动、定位、多列布局

6、浮动最初用于在文本块内浮动图像,float属性成为在网页上创建多列布局最常用的工具之一。随着flexbox和grid的出现,它现在又回到了最初的目的,正如本文所解释的那样。6.1浮动的背景引入float属性是为了允许web开发人员实现包含图像在文本列内浮动的布局,文本在其左侧或右侧环绕。就像你在报纸版面上看到的那样

函数扩展之——内存函数

前言:小伙伴们又见面啦。本篇文章,我们将讲解C语言中比较重要且常用的内存函数,并尝试模拟实现它们的功能。让我们一起来学习叭。目录一.什么是内存函数二.内存函数有哪些1.memcpy(1)库函数memcpy(2)模拟实现memcpy2.memmove(1)库函数memmove(2)模拟实现memmove3.memset4

【大数据】HDFS 的常用命令

HDFS的常用命令1.操作命令1.1创建文件夹1.2列出指定的文件和目录1.3新建文件1.4上传文件1.5将本地文件移动到HDFS1.6下载文件1.7查看文件1.8追写文件1.9删除目录或者文件1.10显示占用的磁盘空间大小1.11HDFS中的文件复制1.12HDFS中的文件移动2.管理命令2.1报告文件系统的基本信息

ElasticSearch(二)

1.DSL查询文档elasticsearch的查询依然是基于JSON风格的DSL来实现的。1.1.DSL查询分类Elasticsearch提供了基于JSON的DSL(DomainSpecificLanguage)来定义查询。常见的查询类型包括:查询所有:查询出所有数据,一般测试用。例如:match_all全文检索(fu

高教杯数学建模A题程序设计要点与思路

2023年是我最后一次参加高教杯大学生数学建模竞赛以后不会再参加了(大四参加意义不太,研究生有研究生的数学建模大赛)很遗憾由于各种原因我们没有能够完成赛题2022年美赛2022年MathorCup2022年国赛2022亚太杯2023年美赛2023年国赛我和我的朋友一共参加了6次比赛6次比赛我交到了很好的朋友然鹅成绩比较

Java 8 新特性解读及应用实践

Java8新特性解读及应用实践一、简介二、Lambda表达式三、流式编程四、日期/时间API1.概述2.LocalDate、LocalTime、LocalDateTime等类的使用3.格式化与解析五、重复注解和类型注解1.概念与作用2.重复注解实例3.类型注解实例六、小结回顾一、简介Java8带来了众多重大改进和新特性

热文推荐