汇编基础介绍——ARMv8指令集(四)

一、CMP 指令

CMP 指令用来比较两个数的大小。在 A64 指令集的实现中,CMP 指令内部调用 SUBS 指令来实现。

1.1、使用立即数的 CMP 指令

使用立即数的 CMP 指令的格式如下。

CMP <Xn|SP>, #<imm>{, <shift>}

上述指令等同于如下指令。

SUBS XZR, <Xn|SP>, #<imm> {, <shift>}

1.2、使用寄存器的 CMP 指令

使用寄存器的 CMP 指令的格式如下。

CMP <Xn|SP>, <R><m>{, <extend> {#<amount>}}

上述指令等同于如下指令。

SUBS XZR, <Xn|SP>, <R><m>{, <extend> {#<amount>}}

1.3、使用移位操作的 CMP 指令

使用移位操作的 CMP 指令的格式如下。

CMP <Xn>, <Xm>{, <shift> #<amount>}

上述指令等同于如下指令。

SUBS XZR, <Xn>, <Xm> {, <shift> #<amount>}

1.4、CMP 指令与条件操作后缀

CMP 指令常常和跳转指令与条件操作后缀搭配使用,例如条件操作后缀 CS 表示是否发生了无符号数溢出,即 C 标志位是否置位,0 表示 C 标志位没有置位。

如下代码使用 CMP 指令来比较如下两个寄存器。

cmp x1, x2
b.cs label

CMP 指令判断两个寄存器是否触发无符号溢出的计算公式与 SUBS 指令类似:

X1 + NOT(X2) + 1 

如果上述过程中发生了无符号数溢出,那么 C 标志位会置 1,则 b.cs 指令将会跳转到 label 处。

下面的代码用来比较 3 和 2 两个立即数。

my_test:mov x1, #3mov x2, #21:cmp x1, x2b.cs 1bret

至于如何比较,需要根据 b 指令后面的条件操作后缀来定。CS 表示判断是否发生无符号数溢出。根据 CMP 指令的运算公式可得,3 + NOT(2) +1,其中 NOT(2)把立即数 2 按位取反,取反后为 0xFFFFFFFFFFFFFFFD。 3 + 0xFFFFFFFFFFFFFFFD + 1 的最终结果为 1,这个过程中发生了无符号数溢出,C 标志位为 1。所以,b.cs 的判断条件成立,跳转到标签 1 处,继续执行。

二、移位指令

常见的移位指令如下。

  • LSL:逻辑左移指令,最高位会被丢弃,最低位补 0,如下(a)图所示。
  • LSR:逻辑右移指令,最高位补 0,最低位会被丢弃,如下(b)图所示。
  • ASR:算术右移指令,最低位会被丢弃,最高位会按照符号进行扩展,如下(c)图所示。
  • ROR:循环右移指令,最低位会移动到最高位,如下(d)图所示。

如下代码使用了 ASR 和 LSR 指令。

ldr w1, =0x8000008a
asr w2, w1, 1
lsr w3, w1, 1

在上述代码中,ASR 是算术右移指令,把 0x8000008A 右移一位并且对最高位进行有符号扩展,最后结果为 0xC0000045。LSR 是逻辑右移指令,把 0x8000008A 右移一位并且在最高位补 0,最后结果为 0x40000045。

三、位操作指令

3.1、与操作指令

与操作主要有两条指令。

  • AND:按位与操作。
  • ANDS:带条件标志位的与操作,影响 Z 标志位。

3.1.1、AND 指令

AND 指令的格式如下。

AND <Xd|SP>, <Xn>, #<imm>
AND <Xd>, <Xn>, <Xm>{, <shift> #<amount>}

AND 指令支持两种方式。

  • 立即数方式:对 Xn 寄存器的值和立即数 imm 进行与操作,把结果写入 Xd/SP 寄存器中。
  • 寄存器方式:先对 Xm 寄存器的值移位操作,然后再与 Xn 寄存器的值进行与操作,把结果写入 Xd/SP 寄存器中。

指令参数说明如下:

shift 表示移位操作,支持 LSL、LSR、ASR 以及 ROR。

amount 表示移位数量,取值范围为 0~63。

3.1.2、ANDS指令

ANDS 指令的格式如下。

ANDS <Xd>, <Xn>, #<imm>
ANDS <Xd>, <Xn>, <Xm>{, <shift> #<amount>}

ANDS 指令支持两种方式。

  • 立即数方式:对 Xn 寄存器的值和立即数 imm 进行与操作,把结果写入 Xd/SP 寄存器中。
  • 寄存器方式:先对 Xm 寄存器的值做移位操作,然后再与 Xn 寄存器的值进行与操作,把结果写入 Xd/SP 寄存器中。

指令参数说明如下。

shift 表示移位操作,支持 LSL、LSR、ASR 以及 ROR。

amount 表示移位数量,取值范围为 0~63。

与 AND 指令不一样的地方是它会根据计算结果来影响 PSTATE 寄存器的 N、 Z、 C、 V 标志位。

如下代码使用 ANDS 指令来对 0x3 和 0 做“与”操作。

mov x1, #0x3
mov x2, #0ands x3, x1, x2
mrs x0, nzcv

“与”操作的结果为 0。通过读取 NZCV 寄存器,我们可以看到其中的 Z 标志位置位了。

3.2、或操作指令

3.2.1、ORR指令

ORR(或)操作指令的格式如下。

ORR <Xd|SP>, <Xn>, #<imm>
ORR <Xd>, <Xn>, <Xm>{, <shift> #<amount>}

ORR 指令支持两种方式。

  • 立即数方式:对 寄存器的值与立即数 Xn imm 进行或操作。
  • 寄存器方式:先对 Xm 寄存器的值做移位操作,然后再与 Xn 寄存器的值进行或操作。

指令参数说明如下。

shift 表示移位操作,支持 LSL 、LSR 、ASR 以及 ROR。

amount 表示移位数量,取值范围为 0~63。

3.2.2、EOR指令

EOR (异或)操作指令的格式如下。

EOR <Xd|SP>, <Xn>, #<imm>
EOR <Xd>, <Xn>, <Xm>{, <shift> #<amount>}

EOR 指令支持两种方式。

  • 立即数方式:对 Xn 寄存器的值与立即数 imm 进行异或操作。
  • 寄存器方式:先对 Xm 寄存器的值做移位操作,然后再与 Xn 寄存器的值进行异或操作。

指令参数说明如下。

shift 表示移位操作,支持 LSL 、LSR 、ASR 以及 ROR。

amount 表示移位数量,取值范围为 0~63。

异或操作的真值表如下。

0 ^ 0 = 0
0 ^ 1 = 1
1 ^ 0 = 1
1 ^ 1 = 0

从上述真值表可以发现 3 个特点。

  • 0 异或任何数 = 任何数。
  • 1 异或任何数 = 任何数取反。
  • 任何数异或自己都等于 。

利用上述特点,异或操作有如下几个非常常用的场景。

使某些特定的位翻转。

例如, 想把 0b10100001 的第 2 位和第 3 位翻转, 则可以对该数与 0b00000110 进行按位异或运算。

10100001 ^ 00000110 = 10100111

交换两个数。

例如,交换两个整数 a=0b10100001 和 b=0b00000110 的值可通过下列语句实现。

a = a^b; //a=10100111
b = b^a; //b=10100001
a = a^b; //a=00000110

在汇编程序里把变量设置为 。

eor x0, x0

判断两个整数是否相等。

bool is_identical(int a, int b)
{return ((a ^ b) == 0);
}

3.3、位清除操作指令

BIC (位清除操作)指令指令用于将寄存器中的某些位清零,而保持其他位不变。其核心作用是选择性地清除(置 0)特定位置的位,常用于权限屏蔽、标志位清除等场景。其格式如下。

BIC <Xd>, <Xn>, <Xm>{, <shift> #<amount>}

BIC 指令支持寄存器方式: 先对 Xm 寄存器的值做移位操作, 然后再与 Xn 寄存器的值进行位清除操作。

指令参数说明如下。

shift 表示移位操作,支持 LSL 、LSR 、ASR 以及 ROR。

amount 表示移位数量,取值范围为 0~63。

BIC 指令的本质是:

Xd = Xn & (~Xm)
  • 将掩码 Xm 按位取反。
  • 将源寄存器(Xn)与取反后的掩码进行按位与操作。

掩码中为 1 的位会清除对应位,为 0 的位保持不变。

3.4、CLZ 指令

CLZ 指令的格式如下。

CLZ <Xd>, <Xn>

CLZ 指令计算为 1 的最高位前面有几个为 0 的位。

如下代码使用了 CLZ 指令。

ldr x1, =0x1100000034578000
clz x0, x1

X1 寄存器里为 1 的最高位是第 60 位,前面还有 3 个为 0 的位,最终 X0 寄存器的值为 3。

四、位段操作指令

4.1、位段插入操作指令

BFI 指令的格式如下。

BFI <Xd>, <Xn>, #<lsb>, #<width>

BFI 指令的作用是用 Xn 寄存器中的 Bit[0, width - 1]替换 Xd 寄存器中的 Bit[lsb, lsb + width - 1], 寄存器中的其他位不变。

BFI 指令常用于设置寄存器的字段。

如下代码将寄存器 X1 的低 4 位插入到寄存器 X0 的第 8~11 位(共 4 位)。

BFI X0, X1, #8, #4  ; 将X1的低4位插入到X0的第8~11位

步骤解析

  • 假设初始值
    • X0 = 0xFFFFFFFFFFFFFFFF(全 1)。
    • X1 = 0x000000000000000F(低 4 位为 1,其余为 0)。
  • 提取源位段
    • X1 的低 4 位为 0b1111
  • 清除目标位段
    • X0 的第 8~11 位被清零,变为 0xFFFFFFF0FFFFFF
  • 插入位段
    • 源位段 0b1111 左移 8 位后为 0x0000000000000F00
    • 合并后 X0 = 0xFFFFFFF0FFFFFF | 0x0000000000000F00 = 0xFFFFFFF0FFFFFFFF

4.2、位段提取操作指令

UBFX 指令的格式如下。

UBFX <Xd>, <Xn>, #<lsb>, #<width>


 

UBFX 指令的作用是提取 Xn 寄存器的 Bit[lsb, lsb + width - 1],然后存储到 Xd 寄存器中。

UBFX 还有一个变种指令 SBFX,它们之间的区别在于:SBFX 会进行符号扩展,例如,如果 Bit[lsb + width - 1] 为 1,那么写到 Xd 寄存器之后,所有的高位都必须写 1,以实现符号扩展。

UBFX 和 SBFX 指令常常用于读取寄存器的某些字段。

如下代码从寄存器 X1 的第 8~15 位(共 8 位)提取值,并零扩展到 X0。

UBFX X0, X1, #8, #8  ; 提取X1的第8~15位,存入X0

步骤解析

  • 假设初始值
    • X1 = 0x0000000000FF00FF(二进制 0b0000...0000111111110000000011111111)。
  • 提取位段
    • 第 8~15 位为 0b00000000(值为 0)。
  • 零扩展
    • 提取的 8 位右移至最低位,左侧补零,结果为 0x0000000000000000
  • 存入目标寄存器
    • X0 = 0x0000000000000000

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

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

相关文章

深入剖析 Electron 性能瓶颈及优化策略

Electron 是一个流行的跨平台桌面应用开发框架&#xff0c;基于 Chromium 和 Node.js&#xff0c;使得开发者可以使用 Web 技术&#xff08;HTML、CSS、JavaScript&#xff09;构建跨平台的桌面应用。许多知名应用如 VS Code、Slack、Discord 和 Figma 都采用了 Electron。然而…

Qt的前端和后端过于耦合(0/7)

最近在写一个软件&#xff0c;这个软件稍微复杂一些&#xff0c;界面大概需要十几个&#xff0c;后端也是要开多线程读各种传感器数据。然后鼠鼠我呀就发现一个致命的问题&#xff0c;那就是前端要求的控件太多了&#xff0c;点一下就需要通知后端&#xff0c;即调用后端的函数…

碰一碰发视频源码搭建定制化开发:支持OEM

在移动互联网与物联网深度融合的当下&#xff0c;“碰一碰发视频” 作为一种创新的信息交互方式&#xff0c;正逐渐应用于营销推广、产品展示、社交互动等多个领域。其核心在于通过近场通信技术&#xff08;如 NFC、蓝牙&#xff09;实现设备间的快速连接&#xff0c;无需复杂操…

机器学习文本特征提取:CountVectorizer与TfidfVectorizer详解

一、文本特征提取概述 在自然语言处理&#xff08;NLP&#xff09;和文本挖掘任务中&#xff0c;文本特征提取是将原始文本数据转换为机器学习模型可以理解的数值特征的关键步骤。scikit-learn提供了两种常用的文本特征提取方法&#xff1a;CountVectorizer&#xff08;词频统…

【PHP】.Hyperf 框架-collection 集合数据(内置函数归纳-实用版)

&#x1f4cc; Article::query()->where(article_id, 6)->select()->first()✍️ 进行数据结果的循环&#xff0c;遍历 1.each() 方法遍历集合中的项目并将每个项目传递给闭包&#xff0c;进行处理数据 Article::query()->get()->each(function ($item) {// 可…

巨兽的阴影:大型语言模型的挑战与伦理深渊

当GPT-4这样的庞然大物能够流畅对话、撰写诗歌、编写代码、解析图像&#xff0c;甚至在某些测试中媲美人类专家时&#xff0c;大型语言模型&#xff08;LLM&#xff09;仿佛成为了无所不能的“智能神谕”。然而&#xff0c;在这令人目眩的成就之下&#xff0c;潜藏着复杂而严峻…

vue根据链接生成二维码 qrcode

vue根据链接生成二维码 qrcode js 需求&#xff1a;后端返回一个完整链接&#xff0c;前端根据链接生成一个二维码 1、安装qrcode插件 npm install qrcode2、引入qrcode,并且使用完整代码 <template> <div><img :src"qrcodeData" class"qrcode…

C# 事件(源代码组件概览)

源代码组件概览 需要在事件中使用的代码有5部分&#xff0c;如图15-4所示&#xff0c;后文会依次进行介绍。这些组件如下 所示 委托类型声明事件和事件处理程序必须有共同的签名和返回类型&#xff0c;它们通过委托类型 进行描述。事件处理程序声明订阅者类中会在事件触发时执…

音视频会议服务搭建(设计方案-数据库sql)-02

前言 衔接上篇文章&#xff0c;这篇是相关的表结构sql语句记录 EchoMeet 会议系统数据库表结构设计 &#x1f4cb; 设计概述 本文档定义了EchoMeet音视频会议系统的完整数据库表结构&#xff0c;采用微服务架构设计&#xff0c;支持高并发、可扩展的会议场景。 &#x1f3af…

MCPA2APPT 智能化演示文稿系统:A2A、MCP、ADK 三大架构全流程自动化

&#x1f680; 项目名称 MCPA2APPT / MultiAgentPPT —— 一站式 A2A MCP ADK 多智能体并发 PPT 生成解决方案 MCPA2APPT 是一款开源 AI PPT 创作神器&#xff0c;基于 A2A&#xff08;Ask-to-Answer&#xff09;、MCP&#xff08;Multi-agent Control Protocol&#xff09;和…

pyinstall打包mysql-connector-python后运行报错的问题!

简单的测试代码 # main.py import mysql.connectorDB_HOSTlocalhost DB_PORT3306 DB_NAMElover DB_USERroot DB_PASSWORDxxxx# 连接数据库 connection mysql.connector.connect(hostDB_HOST,portDB_PORT,databaseDB_NAME,userDB_USER,passwordDB_PASSWORD)if connection.is_c…

应对高并发:淘宝商品评论实时数据 API 高效接入开发实践

在电商平台的运营中&#xff0c;商品评论数据是用户决策、商家优化及平台运营的重要依据。淘宝作为国内领先的电商平台&#xff0c;其商品评论数据具有实时性强、数据量大、并发访问频繁等特点。本文将围绕淘宝商品评论实时数据 API 的高效接入展开&#xff0c;探讨在高并发场景…

踩坑日记:虚拟机桥接模式无法连接网卡

对于一名网安学生&#xff0c;我们渗透测试一般是需要虚拟机使用桥接模式。 但是vm直接设置成桥接模式并不能上网。还要进行如下配置 改一下这个桥接的地方。改成我们主机的网卡。 如何查看主机网卡呢&#xff1f; 设置搜索网络

Android 系统默认的Launcher3,Android 系统的导航栏(通常是屏幕底部)显示的 4 个快捷应用图标,如何替换这4个应用图标为客户想要的。

Android 系统默认的Launcher3, Android 系统的导航栏(通常是屏幕底部)显示的 4 个快捷应用图标, 如何替换这4个应用图标为客户想要的。 开发云 - 一站式云服务平台 按如下方式可以修改应用图标。 diff --git a/packages/apps/Launcher3/res/xml/default_workspace_5x6_no_a…

maker-pdf 文档文字识别,并用python实现

下面我将详细讲解maker-pdf文档文字识别的技术原理、特点&#xff0c;并提供完整的Python实现代码及优化方案。内容结合最新文档和OCR技术实践&#xff0c;适合开发者直接集成到项目中。 一、maker-pdf 核心技术解析 maker-pdf是基于深度学习的端到端OCR工具链&#xff0c;专…

Go基础(Gin)

go mod init my-gin-app 初始化一个 Go 项目&#xff0c;创建一个go.mod文件go mod tidy 自动整理项目依赖&#xff0c;确保go.mod和go.sum文件与代码实际使用的依赖一致go mod init&#xff1a;创建项目的 “依赖说明书”。go mod tidy&#xff1a;整理 “说…

21、鸿蒙学习——使用App Linking实现应用间跳转

简介 使用App Linking进行跳转时&#xff0c;系统会根据接口传入的uri信息&#xff08;HTTPS链接&#xff09;将用户引导至目标应用中的特定内容&#xff0c;无论应用是否已安装&#xff0c;用户都可以访问到链接对应的内容&#xff0c;跳转体验相比Deep Linking方式更加顺畅。…

Cursor无限邮箱续费方法

1.注册无限邮箱2925 2.“其他邮箱” 3.点击左下角添加邮箱 4.管理员身份运行Windos PowerShell 5.输入该指令并运行&#xff0c;修改机器码 irm https://aizaozao.com/accelerate.php/https://raw.githubusercontent.com/yuaotian/go-cursor-help/refs/heads/master/scripts/…

LeetCode Hot100(图论)

200. 岛屿数量 题意 给你一个由 1&#xff08;陆地&#xff09;和 0&#xff08;水&#xff09;组成的的二维网格&#xff0c;请你计算网格中岛屿的数量。 岛屿总是被水包围&#xff0c;并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。 此外&#xff0c;你…

Ubuntu Gnome 安装和卸载 WhiteSur-gtk-theme 类 Mac 主题的正确方法

WhiteSur-gtk-theme 是一个流行的 GNOME 桌面主题&#xff0c;可以让 Ubuntu 的桌面环境看起来像 macOS。以下是安装和卸载 WhiteSur-gtk-theme 的详细步骤&#xff0c;包括解释每个命令的作用。 一、安装 WhiteSur-gtk-theme 1. 准备工作 在安装主题之前&#xff0c;建议确…