Dance with Compiler - EP2

news2024/9/20 12:40:44

今天来熟悉汇编指令。

基本指令特点

str: store value to memory
ldr: load value from memory
stp: store register value to stack
ldp: load stack value to register

更新寄存器的操作,一般结果寄存器是左操作数。
写内存的操作(str),一般寄存器是左操作数,结果内存是右操作数。
读内存操作(ldr),一般寄存器是左操作数,源内存是右操作数。

所以:

  • 读写内存操作,寄存器始终在左边,内存地址始终在右边。
  • 读写堆栈操作,寄存器始终在左边,堆栈内存地址始终在右边。
  • 数学运算操作,结果寄存器在左边

约定:对于32位寄存器,用 Rn表示,64位寄存器,用Xn表示

常见指令

  1. CMP w3, 1

    等价于 SUBS XZR, w3, 1

    SUBS XZR, Xn, #
    功能:从寄存器 Xn 的值中减去一个立即数 #,并将结果存储到 XZR 寄存器,同时更新条件标志寄存器(N, Z, C, V)。
    解释:
    SUBS 代表 “subtract with flags”(减法并设置标志)。它执行减法操作,并且会根据结果更新条件标志寄存器。
    XZR 是一个特殊的寄存器,在 ARMv8 中,它被用作只读零寄存器。任何写入到 XZR 的值都被丢弃,因为 XZR 的值总是 0。因此,XZR 用于忽略操作的结果,但仍然允许更新条件标志。
    Xn 是源寄存器,包含要减去的值。
    # 是立即数,用于从 Xn 中减去。
    减法操作的结果不会存储在 XZR 中,因为 XZR 总是 0。操作的主要目的是更新条件标志以供后续的条件分支指令使用。
    条件标志:
    N(Negative):如果结果为负,则设置 N 标志。
    Z(Zero):如果结果为零,则设置 Z 标志。
    C(Carry):如果减法操作的结果没有借位,则设置 C 标志(即,如果 Xn >= #,则 C 标志被设置)。
    V(Overflow):如果减法操作导致溢出,则设置 V 标志(即结果超出了表示范围)。

  2. sub x9, sp, #16384
    功能:计算并更新寄存器 x9 的值。
    解释:将堆栈指针 sp 的值减去 16384 (0x4000),结果存储在寄存器 x9 中。这里 16384 是堆栈分配或调整的字节数。
    例子:
    如果 sp 的值是 0x8000,那么执行后 x9 的值将是 0x8000 - 0x4000 = 0x4000。

  3. str xzr, [x9, 3968]
    功能:将寄存器中的值存储到内存。
    解释:将寄存器 xzr(零寄存器,其值始终为 0)存储到以 x9 为基地址加上偏移 3968 字节处的内存位置。这实际上是在 x9 + 3968 的地址上写入 0。
    例子:
    如果 x9 的值是 0x4000,则会把 0 存储到内存地址 0x4000 + 3968 = 0x7C00。

  4. stp x29, x30, [sp, -128]!
    功能:将两个寄存器的值存储到堆栈,并更新堆栈指针。
    解释:将寄存器 x29 和 x30 的值存储到以 sp 为基地址减去 128 字节的内存位置,并将堆栈指针 sp 更新到 sp - 128 的位置。! 表示更新堆栈指针。
    例子:
    如果原来的 sp 是 0x7000,这条指令将 x29 和 x30 的值存储到 0x7000 - 128 = 0x6F80 地址,然后将 sp 更新为 0x6F80。

  5. mov x29, sp
    功能:将堆栈指针的值复制到寄存器。
    解释:将堆栈指针 sp 的当前值复制到寄存器 x29 中。通常用于设置帧指针,将其指向当前的堆栈位置。
    例子:
    如果 sp 的值是 0x6F80,执行后 x29 的值将被设置为 0x6F80。

这段 ARM 汇编代码负责从堆栈中加载多个寄存器的值,并最终返回到调用者。下面逐条解释这些指令:

  1. ldp x19, x20, [sp, 16]
    功能:从内存中加载两个寄存器的值。
    解释:从堆栈指针 sp 偏移 16 字节的地址开始,加载两个 64 位寄存器的值,分别存入寄存器 x19 和 x20。
    例子:
    如果 sp 的值是 0x5000,这条指令将从 0x5000 + 16 = 0x5010 的内存地址读取两个 64 位值,并将其存储到 x19 和 x20 中。

  2. cmp w24, w25
    功能:比较两个寄存器的值。
    解释:将寄存器 w24 和 w25 的值进行比较。此操作会设置条件标志,用于后续的条件分支指令。
    例子:
    比较 w24 和 w25 的值,结果将影响后续指令的条件跳转。

  3. cset w1, eq
    功能:设置寄存器的值。
    解释:如果条件标志中的 EQ(Equal,等于)被设置,则将寄存器 w1 设为 1;否则,设为 0。此指令用于基于上一个比较操作的结果设置寄存器值。
    例子:
    如果 w24 等于 w25,则 w1 的值将设置为 1;否则,设置为 0。

  4. cbz w0, .L1301
    功能:条件分支指令。
    解释:如果寄存器 w0 的值为零(cbz 代表 “compare and branch if zero”),则跳转到标签 .L1301 处执行。
    例子:
    如果 w0 的值是 0,程序将跳转到 .L1301 标签处。

  5. cbnz w1, .L1308
    功能:条件分支指令。
    解释:如果寄存器 w1 的值不为零(cbnz 代表 “compare and branch if not zero”),则跳转到标签 .L1308 处执行。
    例子:
    如果 w1 的值是 1,程序将跳转到 .L1308 标签处。

  6. blr x1
    功能:分支到寄存器指定的地址。
    解释:将程序执行的控制权转移到寄存器 x1 中存储的地址。这个指令常用于函数调用或跳转到计算得到的地址。
    例子:
    如果 x1 的值是 0x1000,这条指令会跳转到地址 0x1000 处执行。

  7. bne .L1391
    功能:条件分支指令。
    解释:如果条件标志中的 NE(Not Equal,不相等)标志被设置为 1(即上一个比较结果表明不相等),则跳转到标签 .L1391 处执行。
    例子:
    如果上一个比较操作的结果是不相等,程序将跳转到 .L1391 标签处。

  8. bls .L1300
    功能:条件分支指令。
    解释:如果条件标志中的 LS(Less than or Equal,小于或等于)标志被设置为 1(即上一个比较结果表明小于或等于),则跳转到标签 .L1300 处执行。
    例子:
    如果上一个比较操作的结果是小于或等于,程序将跳转到 .L1300 标签处。

  9. ccmp w24, w28, 0, eq
    功能:条件比较操作。
    解释:将寄存器 w24 和 w28 进行比较,但不会设置条件标志。该指令通常用于与条件分支指令配合使用,其中 0 表示不改变标志,eq 表示检查等于条件。
    例子:
    比较 w24 和 w28 的值,并检查它们是否相等,但不直接影响标志寄存器的状态。

  10. bcc .L1389
    功能:条件分支指令。
    解释:如果条件标志中的 CC(Carry Clear,进位标志清除)被设置为 1(即上一个比较结果表明小于),则跳转到标签 .L1389 处执行。
    例子:
    如果上一个比较操作的结果是小于,程序将跳转到 .L1389 标签处。

  11. ubfx x4, x4, 0, 48
    功能:从寄存器中提取无符号位域。
    解释:从寄存器 x4 中提取从位 0 开始的 48 位,并将结果存储回 x4。ubfx 代表 “unsigned bit field extract”。
    例子:
    如果 x4 的值是 0xFFFFF000,提取的结果将是 0xFFF000。

  12. prfm PLDL1KEEP, [x4]
    功能:数据预取。
    解释:预取缓存行以提高数据访问速度。PLDL1KEEP 表示将数据从 L1 数据缓存中保留到 L1 中,并从内存中读取。[x4] 指定了预取的地址。
    例子:
    如果 x4 的值是 0x2000,这条指令将从内存地址 0x2000 预取数据到 L1 数据缓存。

ARM 特色:条件指令

CCMP Xn, #imm, #nzcv, cond

  • 其中,cond 是说是否执行 CCMP 语句的比较操作的条件,cond 的内容来自 NZCV,也就是上一个算术操作的结果(手册里说得很不清晰)。
  • CCMP 输出的 flags = if cond then compare(Xn, #imm) else #nzcv

CCMP
在这里插入图片描述

在这里插入图片描述

所以

	cmp	    x1, 0 (转化成 x1 - 0 操作,会设置 NZCV标记)
	ccmp	w24, w28, 0, eq   (如果上一个cmp不满足 eq 条件,也就是说没有设置 z 标记,则不执行 w24 和 w28 的比较,但会强制把当前指令的 NZCV 标记设置成 0。否则,比较 w24 和 w28,并按照一般 cmp 规则设置 NZCV 标记)
	bcc	    .L1389  (根据 NZCV 标记决策跳转,bcc 表示如果 C 位被设置了,则跳转,即w24 >= w28 则跳转)

翻译成 C 语言的理解就是:

if (x1 == 0 && w24 >= w28) {
// jump
}

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

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

相关文章

不同工况下的迁移轴承故障诊断,融合SE注意力机制的Resnet18迁移学习,附MATLAB代码...

概要 迁移学习(Transfer Learning)是一种在机器学习中广泛应用的技术,它利用在一个任务上获得的知识来帮助解决另一个相关任务。迁移学习尤其适用于数据量有限或训练成本较高的情况。它可以显著提高模型的性能和训练效率。 本期采用MATLAB语…

新材料 金属3D打印发展的加速器

在金属3D打印的广阔舞台上,材料性能犹如舞台的台柱,直接决定了打印工件性能的优劣。从强度、硬度到耐腐蚀性、抛光性及导热性,每一项指标都紧密关联着材料的选择,而优质材料正是推动这项技术跨越边界、深入更多行业领域的核心动力…

一个vue重新回顾,好多年前写的

在校期间简单跟着视频学习的代码,后面上传到github仓库就一直没有使用了,今天重新加载,重新启动。下面是启动时候遇到的问题,主要原因是我这部电脑是新电脑,很多环境还没有搭建。 成功启动后的页面效果 这里采用的思…

oauth2 方式获取outlook邮箱收件箱(python)

1.在Azure 门户注册应用程序 微软文档地址 重定向的地址配置(微软地址): https://login.microsoftonline.com/common/oauth2/nativeclient 注册应用地址 2.程序代码 #安装包以及需要的驱动 pip3 install playwrightplaywright install import base64 import jso…

服务器模型 Reactor 和 Proactor

Proactor 具体流程如下: 处理器发起异步操作,并关注 IO 完成事件;事件分离器等待操作完成事件;分离器等待过程中,内核并行执行实际的 IO 操作,并将结果存储入用户自定义的缓冲区,最后通知事件分…

零工市场小程序:自由职业者的日常工具

零工市场小程序多功能且便捷,提供了前所未有的灵活性和工作效率。这类小程序不仅改变了自由职业者的工作方式,也重塑了劳动力市场的格局。 一、零工市场小程序的特点 即时匹配:利用先进的数据算法,零工市场小程序能够快速匹配自由…

ASP.Net Core 因集成WebSocket导致Swagger UI显示错误

文章目录 前言一、ApiExplorerSettings二、解决Swagger UI显示问题 前言 Swagger UI 本身并不支持直接展示或测试 WebSocket 端点。Swagger(现在称为 OpenAPI)及其 UI 实现主要是为 RESTful API 设计的,这些 API 基于 HTTP 请求/响应模型。W…

IDEA加载工程报错Error Loading Project: Cannot load module demo.iml解决

spring boot工程由于工程名字为demo不太好,直接更改了这个工程的名字,主要操作了包括重命名项目文件夹、修改IDEA中的项目名称、模块名称、包名称、以及相关的配置文件等。 然后再打开工程,报错Error Loading Project: Cannot load module de…

MyBatis ——在java层面对MySQL数据库进行操作

目录 MyBatis 是一款优秀的 持久层框架,用于简化JDBC(java操作数据库)的开发; 使用MyBatis 查询所有用户数据的过程 Lombok是一个实用的]ava类库,能通过注解的形式 简化 JavaBean的代码 注解: 引入Myb…

Oracle之用TO_CHAR函数将日期格式转化为不带前导零的月份和日

要求: 1、日期格式转化成字符串格式,月和日前面的0需要去掉,如日期2024-09-06需要转化成2024-9-6; 2、如果用截取拼接函数写法就会复杂,最好用TO_CHAR函数格式化实现。 正确写法: SELECT TO_CHAR(SYSDAT…

使用cage工具包生成验证码

目录 1. 导入依赖2. 控制类3. 测试 1. 导入依赖 <!-- 验证码工具 --><dependency><groupId>com.github.cage</groupId><artifactId>cage</artifactId><version>1.0</version></dependency>2. 控制类 RestControl…

SD-WAN解决外贸企业网络搭建问题

在全球化浪潮下&#xff0c;外贸企业日益感受到互联网和数字化技术对业务发展的重要性。作为一种创新的网络解决方案&#xff0c;SD-WAN&#xff08;软件定义广域网&#xff09;正成为外贸企业网络升级的重要助力。本文将深入剖析SD-WAN如何有效解决外贸企业网络搭建中的关键问…

ubuntu java

1、安装&#xff1a;https://zhuanlan.zhihu.com/p/565274672 遇到 sudo kill 8544 2、然后可以正常安装 编写hello world: https://blog.csdn.net/qq_33523925/article/details/92410963 安装IDEA Linux系统安装IDEA保姆级教程_linux安装idea-CSDN博客 3、idea如何设置…

【第0006页 · 数组】寻找重复数

【前言】本文以及之后的一些题解都会陆续整理到目录中&#xff0c;若想了解全部题解整理&#xff0c;请看这里&#xff1a; 第0006页 寻找重复数 今天想讨论的一道题在 LeetCode 上评论也是颇为“不错”。有一说一&#xff0c;是道好题&#xff0c;不过我们还是得先理解了它才…

北京理工大学开设仓颉实践课程,培养特色化软件人才

为响应国家软件发展战略&#xff0c;培养满足产业发展需求的特色化软件人才&#xff0c;北京理工大学信息技术创新学院率先把仓颉语言引入到大二暑期的实践课程中。在今年暑期为期3周的实践课中&#xff0c;信息技术创新学院教研中心副主任徐礼文老师开设了“仓颉语言HarmonyOS…

Git 撤回commit

上一篇&#xff0c;Git撤销add&#xff0c;其实已经讲了用reset命令可以取消commit&#xff0c;这里再啰嗦下。先看&#xff1a; git如何撤回已经commit • Worktile社区 首先明确一点&#xff0c;无论是commit还是撤销commit&#xff0c;都是在本地暂存区操作&#xff0c;而…

CTFHub技能树-Git泄漏-Stash

目录 一、前提知识 1.什么是git stash 2.git文件目录结构 3.git中对象指向 二、解题过程 方法一&#xff1a;使用GitHack 方法二&#xff1a;使用Git_Extract工具&#xff0c;这个是自动解析不用git stash等操作&#xff0c;直接得到flag 当前大量开发人员使用git进行版本…

C/C++:C语言中的__FILE__、__LINE__等几种C标准用法

C语言中的几种特殊标准定义 __FILE__ &#xff1a;正在编译文件的文件名__LINE__ &#xff1a;正在编译文件的行号__DATE__&#xff1a;编译时刻的日期字符串 如“Sep 22 2020”__TIME__&#xff1a;编译时刻的时间字符串 如”10:00:00“__STDC__&#xff1a;判断该文件是不是…

网关功能介绍

在微服务架构中&#xff0c;网关&#xff08;API Gateway&#xff09;扮演着至关重要的角色&#xff0c;它作为客户端和微服务之间的中介&#xff0c;负责路由、过滤、认证、限流等职责。以下是一些常见的网关实现&#xff1a; Spring Cloud Gateway&#xff1a; Spring Cloud …

【佳学基因检测】网站加密证书失效后,如何移除并为新的证书安装准备环境?

【佳学基因检测】网站加密证书失效后&#xff0c;如何移除并为新的证书安装准备环境&#xff1f; 当WoTrus DV Server CA证书失效后&#xff0c;你需要确保你的Nginx配置中不再引用该证书&#xff0c;并且移除或替换相关的证书文件。以下是具体步骤&#xff1a; 1. 确认Nginx…