通用指令(汇编)

  • 一、数据处理指令
    • 1)数学运算
            • 数据运算指令的格式
            • 数据搬移指令
            • 立即数
            • 伪指令
            • 加法指令
            • 带进位的加法指令
            • 减法指令
            • 带借位的减法指令
            • 逆向减法指令
            • 乘法指令
            • 数据运算指令的扩展
    • 2)逻辑运算
            • 按位与指令
            • 按位或指令
            • 按位异或指令
            • 左移指令
            • 右移指令
            • 位清零指令
    • 3)比较指令
            • 怎么影响到CPSR寄存器中的状(N, Z, C, V)
            • 比较指令
            • ARM指令的条件码
  • 二、跳转指令
    • 1)跳转指令
            • 跳转指令
  • 三、Load / Srore指令
    • 1)内存访问指令
            • 写内存
            • 读内存
    • 2)ARM指令的寻址方式
            • 立即寻址
            • 寄存器寻址
            • 寄存器移位寻址
            • 寄存器间接寻址
            • 基址加变址寻址
            • 基址加变址寻址的索引方式
            • 多寄存器内存访问指令的寻址方式
    • 3)栈的种类与使用

一、数据处理指令

数据处理指令(数学运算、逻辑运算)

1)数学运算

32位处理器什么意思:单次运算数据的能力,单次最大可处理32位的数据

数据运算指令的格式

《操作码》《目标寄存器》《第一操作寄存器》《第二操作数》
操作码: 表示执行哪种操作
目标寄存器: 表示存储运算的结果
第一操作寄存器: 存储第一个参与运算的寄存器(只能是寄存器)
第二操作数: 存储第二个参与运算的数据(寄存器、立即数都可以)

数据搬移指令

MOV R1, #1
MOV R2, R1 // R2 = R1
MOV PC, #7 // 可以更改PC的值,但是系统会默认把后两位改成0,7八进制>111系统会自动改成4>100
MVN R0, #0xFF // R0 = ~0xFF R0的内容就是0xFFFFFF00

立即数

立即数的本质是包含在指令当中的数,属于指令的一部分,这条执行是一起编译成机器码的
优点:
取值的时候就可以直接读取到CPU,不用单独去内存读取,速度快
缺点:
不能是任意的32位的数字,有局限性
MOV R1, #0x12345678 //不可以执行,因为数字太大
MOV R1, #0x12 //可以执行

伪指令

MOV R1, #0xFFFFFFFF
//当执行这条指令的时候显然这个数字太大,但是可以编译成功,是系统自动会将这条指令替换成 MVN R1, #0x00000000 这样就和MOV R1, #0xFFFFFFFF 指令执行的效果一样,这样的行为前提是两条指令要达到的效果相同

加法指令

ADD R1, R2, R3 //R1 = R2+R3

带进位的加法指令

ADC R5, R2, R4 // R5 = R2 + R4 + ‘CPSR->C’

1.编程实现使用32bit的ARM处理器实现两个128位的数据的加法运算。

第一个数的bit[31:0]、bit[63:32]、bit[95:64]、bit[127:96]分别存储在R1、R2、R3、R4寄存器
第二个数的bit[31:0]、bit[63:32]、bit[95:64]、bit[127:96]分别存储在R5、R6、R7、R8寄存器
运算结果的bit[31:0]、bit[63:32]、bit[95:64]、bit[127:96]分别存储在R9、R10、R11、R12寄存器

@ 第一个数 0x00000004 00000002 FFFFFFFF 00000004MOV R1, #0xFFFFFFFFMOV R2, #0x00000002MOV R3, #0xFFFFFFFFMOV R4, #0x00000004@ 第二个数 0x00000005 00000004 00000003 00000002MOV R5, #0x00000002	MOV R6, #0x00000003MOV R7, #0x00000004MOV R8, #0x00000005@ 运算结果ADDS R9 , R1, R5	//加 'S' 可以影响到CPSR寄存器,高位运算时,可以看出低位有没有进位ADCS R10, R2, R6ADCS R11, R3, R7ADC  R12, R4, R8
减法指令

SUB R1, R2, R3 //R1 = R2-R3

带借位的减法指令

SBC R5, R2, R4 // R5 = R2 - R4 - ‘~CPSR->C’ 取反

逆向减法指令

RSB R1, R2, #3 //R1 = 3-R2

乘法指令

MUL R1, R2, R3 //R1 = R2*R3 乘法指令只能是两个寄存器执行

数据运算指令的扩展

MOV R1, R2, LSL #1 //R1 = (R2<<1)

2)逻辑运算

按位与指令

AND R1, R2, R3 //R1 = R2&R3

按位或指令

ORR R1, R2, R3 //R1 = R2 | R3

按位异或指令

EOR R1, R2, R3 //R1 = R2 ^ R3

左移指令

LSL R1, R2, R3 //R1 = R2 << R3

右移指令

LSR R1, R2, R3 //R1 = R2 >> R3

位清零指令

MOV R2, #0xFF
BIC R1, R2, #0x0F
//第二操作数的哪一位为1,就把第一寄存器中的哪一位清零,然后将结果放入目标寄存器中

3)比较指令

怎么影响到CPSR寄存器中的状(N, Z, C, V)

数据运算指令对条件位CPSR寄存器中的状(N, Z, C, V)的影响
默认情况下数据运算不会对条件位产生影响,当在指令后加后缀‘S’后可以影响
MOV R2, #3
SUBS R1, R2, #5 //将会对 N 状态位产生影响

比较指令

CMP R1, R2
本质是一条(SUBS),只是没有将运算结果放入寄存器当中,是看CSPR寄存器状态位(N, Z, C, V)

==	Z=1
!=	Z=0
<	C=0
<=	C=0 或 Z=1
>	C=1 且 Z=0 
>=	C=1
  MOV R1, #1MOV R2, #2CMP R1, R2BEQ FUNC	@ 执行逻辑:if(EQ){B FUNC}	本质:if(Z==1){B FUNC}BNE FUNC	@ 执行逻辑:if(NE){B FUNC}	本质:if(Z==0){B FUNC}MOV R3, #3MOV R4, #4MOV R5, #5FUNC:MOV R6, #6MOV R7, #7@ ARM指令集中大多数指令都可以带条件码后缀MOV R1, #1MOV R2, #2CMP R1, R2MOVGT R3, #3@ 练习:用汇编语言实现以下逻辑int R1 = 9;int R2 = 15;START:if(R1 == R2){STOP();}else if(R1 > R2){			R1 = R1 - R2;goto START;}else{R2 = R2 - R1;goto START;}@ 练习答案:MOV R1, #9MOV R2, #15START:CMP R1,R2BEQ STOPSUBGT R1, R1, R2SUBLT R2, R2, R1B STARTSTOP:				B STOP

在这里插入图片描述

ARM指令的条件码

ARM指令集中大多数指令都可以带条件码后缀(如:SUBEQ)

在这里插入图片描述

二、跳转指令

1)跳转指令

跳转指令

有三种方式

第一种方法:直接去修改PC的值(不建议使用,因为需要自己计算绝对地址)

MAIN:MOV R1, #1MOV R2, #2MOV PC, #0x16MOV R3, #3FUNC:MOV R4, #4MOV R5, #5MOV R6, #6

第二种方法:不带返回的跳转指令,本质就是将PC寄存器的值修改成跳转标号下第一条指令的地址

MAIN:MOV R1, #1MOV R2, #2B	FUNCMOV R3, #3FUNC:MOV R4, #4MOV R5, #5MOV R6, #6

第三种方法;带返回的跳转指令,本质就是将PC寄存器的值修改成跳转标号下第一条指令的地址,同时将跳转指令的下一条指令的地址存储到LR

MAIN:MOV R1, #1MOV R2, #2BL	FUNCMOV R3, #3FUNC:MOV R4, #4MOV R5, #5MOV R6, #6MOV PC, LR

三、Load / Srore指令

Load / Srore指令(访问(读写)内存)

1)内存访问指令

Load/Srore指令:访问(读写)内存 当LD开头的指令 内存读数据到CPU 当ST开头的指令 把CPU中的数据存到内存当中

写内存
	@ MOV R1, #0xFFFFFFF1@ MOV R2, #0x40000000@ STR R1, [R2]		默认是写入一个字(四个字节)的数据@ STRB R1, [R2]  内存中写入'B'一个字节的数据'F1'@ STRH R1, [R2]  内存中写入'H'两个字节的数据'FFF1'@ R2->0x40000000内存空间 = R1的数据
读内存
	@ MOV R1, #0xFFFFFFF1@ MOV R2, #0x40000000@ LDR R3, [R2]	R3 = 默认内存读出一个字(四个字节)的数据@ LDRB R3, [R2]	R3 = 内存读出一个字节的数据@ LDRH R3, [R2]	R3 = 内存读出两个字节的数据@ R3 = R2->0x40000000内存空间的数据

2)ARM指令的寻址方式

寻址方式就是CPU去寻找操作数的方式

立即寻址

@ MOV R1, #1
@ ADD R1, R2, #1

寄存器寻址

@ ADD R1, R2, R3

寄存器移位寻址

@ MOV R1, R2, LSL #1

寄存器间接寻址

@ STR R1, [R2]

基址加变址寻址
		@ MOV R1, #0xFFFFFFFF@ MOV R2, #0x40000000@ MOV R3, #4@ STR R1, [R2,R3]@ 将R1寄存器中的数据写入到R2+R3指向的内存空间@ STR R1, [R2,R3,LSL #1]@ 将R1寄存器中的数据写入到R2+(R3<<1)指向的内存空间
基址加变址寻址的索引方式

前索引

		@ MOV R1, #0xFFFFFFFF@ MOV R2, #0x40000000@ STR R1, [R2,#8]@ 将R1寄存器中的数据写入到R2+8指向的内存空间@ LDR R2, [R2,#8]@ 将R2+8指向的内存空间的数据写入到R2寄存器中

后索引

		@ MOV R1, #0xFFFFFFFF@ MOV R2, #0x40000000@ STR R1, [R2],#8@ 将R1寄存器中的数据写入到R2指向的内存空间,然后R2自增8@ LDR R1, [R2],#8@ 将R2+8指向的内存空间的数据写入到R2寄存器中,然后R1自增8

自动索引

		@ MOV R1, #0xFFFFFFFF@ MOV R2, #0x40000000@ STR R1, [R2,#8]!@ 将R1寄存器中的数据写入到R2+8指向的内存空间,然后R2自增8@ LDR R6, [R2,#8]!@ 将R2+8指向的内存空间的数据写入到R6寄存器中,然后R6自增8
多寄存器内存访问指令的寻址方式

在这里插入图片描述

		@ MOV R1, #1@ MOV R2, #2@ MOV R3, #3@ MOV R4, #4@ MOV R11,#0x40000020@ STMIA R11!,{R1-R4}@ 先存储数据,后增长地址@ STMIB R11!,{R1-R4}@ 先增长地址,后存储数据@ STMDA R11!,{R1-R4}@ 先存储数据,后递减地址@ STMDB R11!,{R1-R4}@ 先递减地址,后存储数据

3)栈的种类与使用

栈的概念

栈的本质就是一段内存,程序运行时用于保存一些临时数据如局部变量、函数的参数、返回值、以及程序跳转时需要保护的寄存器等

栈的分类

在这里插入图片描述
增栈:压栈时栈指针越来越大,出栈时栈指针越来越小
减栈:压栈时栈指针越来越大,出栈时栈指针越来越小
满栈:栈指针指向最后一次压入到栈中的数据,压栈时需要先移动栈指针到相邻位置然后再压栈
空栈:栈指针指向最后一次压入到栈中的数据的相邻位置,压栈时可直接压栈,之后需要将栈指针移动到相邻位置

栈分为空增(EA)、空减(ED)、满增(FA)、满减(FD)四种
ARM处理器一般使用满减栈

		MOV R1, #1MOV R2, #2MOV R3, #3MOV R4, #4MOV R11,#0x40000020STMFD R11!,{R1-R4}LDMFD R11!,{R6-R9}@ 结果 R6 = 1, R7 = 2, R8 = 3, R9 = 4

栈的应用举例

1.叶子函数的调用过程举例

@ 初始化栈指针MOV SP, #0x40000020
MIAN:MOV R1, #3MOV R2, #5BL  FUNCADD R3, R1, R2B STOPFUNC:@ 压栈保护现场STMFD SP!, {R1,R2}MOV R1, #10MOV R2, #20SUB R3, R2, R1@ 出栈恢复现场LDMFD SP!, {R1,R2}MOV PC, LR

2.非叶子函数的调用过程举例

		MOV SP, #0x40000020
MIAN:MOV R1, #3MOV R2, #5BL  FUNC1ADD R3, R1, R2B STOP		
FUNC1:STMFD SP!, {R1,R2,LR}MOV R1, #10MOV R2, #20BL  FUNC2SUB R3, R2, R1LDMFD SP!, {R1,R2,LR}MOV PC, LR
FUNC2:STMFD SP!, {R1,R2}MOV R1, #7MOV R2, #8MUL R3, R1, R2LDMFD SP!, {R1,R2}MOV PC, LR@ 执行叶子函数时不需要对LR压栈保护,执行非叶子函数时需要对LR压栈保护

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

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

相关文章

Kernel Exception导致手机重启案例分析

和你一起终身学习&#xff0c;这里是程序员Android 经典好文推荐&#xff0c;通过阅读本文&#xff0c;您将收获以下知识点: 一、高温触发 Kernel Exception 重启问题二、解决方案三、提高电池温度方案 一、 高温触发 Kernel Exception 重启问题 手机 电池温度 默认60度以上高温…

【css】css位置布局position

position 属性规定应用于元素的定位方法的类型。元素其实是通过使用top、bottom、left 和 right 属性来定位的。但是&#xff0c;需要首先设置了 position 属性&#xff0c;否则这些属性将不起作用。根据不同的 position 值&#xff0c;它们的设置特点不同。 其有五个不同的位…

elfk

1. 2. ​​​​​​​ 3. 4. 5.

文件或目录损坏且无法读取

如上图报错&#xff0c;我们直接用cmd命令输入【CHKDSK C: /F】然后回车 电脑重启后可以了&#xff0c;希望能帮助各位小伙伴

K8S系列文章之 离线安装自动化工具Ansible

参考 文档 离线安装 Ansible - DevOps - dbaselife 一、Ansible简介 Ansible是一款开源的IT配置管理工具&#xff0c;常被IT界的小伙伴们用于自动化的场景&#xff0c;多用在服务部署、配置管理方面。配置文件采用最常见的yaml格式&#xff0c;学习起来也是比较容易&#xff…

【前端实习生备战秋招】—HTML 和 CSS面试题总结(三)

【前端实习生备战秋招】—HTML 和 CSS面试题总结&#xff08;三&#xff09; 1.行内元素有哪些&#xff1f;块级元素有哪些&#xff1f; 空(void)元素有那些&#xff1f; CSS 规范规定&#xff0c;每个元素都有 display 属性&#xff0c;确定该元素的类型&#xff0c;每个元素…

学python的心得体会1000字,学python的心得体会2000字

这篇文章主要介绍了学python的心得体会2000字&#xff0c;具有一定借鉴价值&#xff0c;需要的朋友可以参考下。希望大家阅读完这篇文章后大有收获&#xff0c;下面让小编带着大家一起了解一下。 1. 初学者应该从简单的练习开始&#xff0c;先掌握基本的语法和概念&#xff0c;…

IT 基础架构自动化

什么是 IT 基础架构自动化 IT 基础架构自动化是通过使用技术来控制和管理构成 IT 基础架构的软件、硬件、存储和其他网络组件来减少人为干预的过程&#xff0c;目标是构建高效、可靠的 IT 环境。 为什么要自动化 IT 基础架构 为客户和员工提供无缝的数字体验已成为企业的当务…

【H5】盘点HTML5新特性

html5总的来说比html4多了十个新特性&#xff0c;但其不支持ie8及ie8以下版本的浏览器 文章目录 一、语义标签二、增强型表单三、音频和视频四、Canvas绘图五、SVG绘图六、地理定位七、拖放API八、Web Worker九、Web Storage十、WebSocket 一、语义标签 html5语义标签&#x…

10_Vue3 其它的组合式API(Composition API)

Vue3 中的其它组合式API 1.shallowReactive 与 shallowRef 2. readonly 与 shallowReadonly 3.toRaw 与 markRaw 4.customRef 5.provide 与 inject 6.响应式数据的判断

AIGC:【LLM(四)】——LangChain+ChatGLM:本地知识库问答方案

文章目录 一.文件加载与分割二.文本向量化与存储1.文本向量化(embedding)2.存储到向量数据库 三.问句向量化四.相似文档检索五.prompt构建六.答案生成 LangChainChatGLM项目(https://github.com/chatchat-space/langchain-ChatGLM)实现原理如下图所示 (与基于文档的问答 大同小…

Qt--QPlugin插件

写在前面 Qt–动态链接库一文中提到&#xff0c;动态方式加载dll只能加载 extern "C“ 的导出函数&#xff0c;而无法加载类&#xff0c;因此可以使用Qt提供的插件来实现导出类的动态加载。 QPlugin是Qt插件框架的一部分&#xff0c;是一种轻量级的插件系统&#xff0c;…

网络防御(7)

课堂实验 R1 [Huawei] int g0/0/0 [Huawei-GigabitEthernet0/0/0]ip add 100.1.12.2 24 protocolAug 1 2023 10:24:09-08:00 Huawei gOlIFNET/4/LINK STATE(1)[4]:The1ineIp on the interface GigabitEthernet0/0/0 has entered the Up state. [Huawei-GigabitEthernet0/0/…

安全渗透知识总结二

目录 一、html实体编码 1、Unicode字符编码 2、字符的数字表示 3、常见实体编码 4、url 协议 主机 http状态码 http常用的状态码 端口 常见协议端口 查询参数 锚点 url字符 urlcode字符 绝对url和相对url 二、字符编码 Ascll字符集 html字符集 html的url编码 …

Linux CentOS安装NVIDIA GPU驱动程序和NVIDIA CUDA工具包

要在CentOS上安装NVIDIA驱动程序和NVIDIA CUDA工具包&#xff0c;您可以按照以下步骤进行操作&#xff1a; 1. 准备工作&#xff1a; 确保您的系统具有兼容的NVIDIA GPU。您可以在NVIDIA官方网站上查找支持CUDA的GPU型号列表。如果您之前已经安装了Nouveau驱动程序并禁用了它…

【网关】Shenyu网关自动注册和同步元数据和URL,Shenyu-admin从nacos同步数据方案

Shenyu官网数据同步设计方案如下面图&#xff0c;同步方式支持 Zookeeper、Http 长轮询、Websocket、Nacos、Etcd 和 Consul等。我们选择的时候&#xff0c;要小心配置参数&#xff0c;这里我以官网http和自实现的nacos为例。 官网示例代码 http方式注册 yml配置admin的账号信息…

JVM之垃圾回收器

1.如何判断对象可以回收 1.1 引用计数法 什么是引用计数器法 在对象中添加一个引用计数器&#xff0c;每当有一个地方引用它时&#xff0c;计数器值就加一&#xff1b;当引用失效时&#xff0c;计数器值就减一&#xff1b;任何时刻计数器为零的对象就是不可能再被使用的。 …

yolo txt 转 labelme json 格式

talk is cheap show me the code! def convert_txt_to_labelme_json(txt_path, image_path, output_dir, image_fmt.jpg):# txt 转labelme json# 将yolo的txt转labelme jsontxts glob.glob(os.path.join(txt_path, "*.txt"))for txt in txts:labelme_json {versio…

LeetCode150道面试经典题-删除有序数组中的重复项(简单)

1.题目 给你一个 升序排列 的数组 nums &#xff0c;请你 原地 删除重复出现的元素&#xff0c;使每个元素 只出现一次 &#xff0c;返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。然后返回 nums 中唯一元素的个数。 考虑 nums 的唯一元素的数量为 k &#xff0c…

Prometheus实现系统监控报警邮件

Prometheus实现系统监控报警邮件 简介 Prometheus将数据采集和报警分成了两个模块。报警规则配置在Prometheus Servers上&#xff0c; 然后发送报警信息到AlertManger&#xff0c;然后我们的AlertManager就来管理这些报警信息&#xff0c;聚合报警信息过后通过email、PagerDu…