汇编基础语法及其示例

news2025/1/31 8:36:52

1.汇编指令

1.1汇编指令的基本格式

<opcode>{<cond>}{s}  <Rd> , <Rn> , <shifter_operand>

<功能码>{<条件码>}{cpsr影响位}  <目标寄存器> , <第一操作寄存器> , <第二操作数>

注:第一操作寄存器只能是寄存器, 不能写数值

        第二操作数可以写寄存器名, 也可以写#一个数值

        汇编不区分大小写

         操作数可以是一个寄存器,也可以是一个立即数         

         立即数:能够经过编码后保存到指令空间中直接当作指令一部分去执行的数据。一个32位指令空间中预留了12位空间保存当前操作数, 可以通过某一个规则对操作数进行处理,将处理后数值放在这12个空间中。所以处理完能够保存到12位空间中的数据就是立即数。通常通过循环右移看是否能得到一个0-255之间的数,如果可以,说明该数据就是立即数

1.2数据处理指令

1.2.1数据搬移指令

1.mov {条件码}  Rd  ,Sh~

将操作数搬移到目标寄存器中

mov R1 , #0x1

MOV R2, R1

2.mvn {条件码} Rd Sh~

将操作数按位取反后搬移到目标寄存器中

mvn R1 , #0x1

MVN R2, R1

3.通过伪指令实现非立即数的搬移:ldr  Rd, =非立即数

ldr Rd , =0x81

1.2.2数据移位指令

1.逻辑左移

lsl{<cond>}  Rd , Rn , Sh~

将Rn左移Sh~位存到Rd中

2.逻辑右移

lsr{<cond>}  Rd , Rn , Sh~

将Rn右移Sh~位存到Rd中

3.循环右移

ror{<cond>}  Rd , Rn , Sh~

将Rn循环右移Sh~位存到Rd中

LSL R1 , R2, #(0x1<<2)

LSR R1 , R2, #2)

1.2.3位运算指令

1.与, 与0清零,与1不变

and {<cond>} Rd , Rn , Sh~

and R1, r2 , #(0x1<<2)

将Rn与Sh~进行与运算存于Rd

2.或,有1为1, 全0为0

orr {<cond>} Rd , Rn , Sh~

Orr r1, r2, #(0x1<<2)

将Rn与Sh~进行或运算存于Rd

3.异或 ,相同为0, 不同为1

eor {<cond>} Rd , Rn , Sh~

Eor R2, R1, #(0x1<<0)

将Rn与Sh~进行异或运算存于Rd

4.按位取反,01交换

mvn(见搬移指令2)

5,按位清零,指为1,清为0

bic {<cond>} Rd , Rn , Sh~

将Rn与Sh~取反进行与运算存于Rd

bic r1, r2, #(0x1<<2)   ===  and r1, r2, #(~(0x1<<2))


1.2.4算术运算指令

1.加法指令

add{<cond>}{s}  Rd, Rn,Sh~

Rd = Rn+Sh~ 

adc{<cond>}{s}  Rd, Rn,Sh~

Rd = Rn+Sh~+cpsr寄存器的c位 

2.减法指令

sub {<cond>}{s}  Rd, Rn,Sh~

Rd = Rn-Sh~ 

sbc{<cond>}{s}  Rd, Rn,Sh~

Rd = Rn-Sh~-cpsr寄存器的c位 

3.乘法指令

mul{<cond>}{s}  Rd, Rn,Sh~

Rd = Rn*Sh~

 

注 :{s}存在时运算,加法进位和减法不借位时,cpsr位置1

32位处理器进行64位数据运算时先低八位,后高八位,低位运算影响c位,高位运算考虑c位 


1.2.5比较指令

1.cmp Rn , Sh~

将Rn和Sh~比较,本质是将二者进行减法运算,并将结果存到cpsr寄存器 的nzcv位,通常和条件码一起使用

2.tst Rd, #(0x1<<N)

判断第N位是否为0.

3.TEQ Rd , sh~

判断二者是否相等

只能影响到z位,无法影响到cvn位


 

1.2.6跳转指令

1.b 标签

跳转到指定标签下,跳转后LR寄存器不保存程序的返回地址

2.bl 标签

跳转到指定标签下,跳转后LR寄存器保存程序的返回地址

 

 

可实现程序到循环执行操作 ,比如累乘和阶乘


1.2.7内存读写指令

类比c语言通过指针读写地址下内存中的数据

*((unsigned int*)0x12345678) = 数值

向内存中写

1.str Rd,[目标地址]

将Rd中的四字节数据写入到目标地址对应的内存中

2.strh Rd,[目标地址]

将Rd中的2字节数据写入到目标地址对应的内存中

3.strb Rd,[目标地址]

将Rd中的1字节数据写入到目标地址对应的内存中

向内存中读

4.ldr Rd,[目标地址]

从目标地址对应的内存中读取4字节数据保存到Rd中

5.ldrh Rd,[目标地址]

从目标地址对应的内存中读取2字节数据保存到Rd中

6.ldrb Rd,[目标地址]

从目标地址对应的内存中读取1字节数据保存到Rd中

此外还分前索引,后索引和自动索引

前索引:以基地址偏移后为首地址读写

str Rd,[基地址, 偏移量]

将Rd的数据写入到基地址+偏移量为首地址到内存中

ldr Rd,[基地址, 偏移量]

从基地址+偏移量为首地址到内存中读取数据保存到Rd中

后索引:以基地址进行为首地址进行读写,之后基地址在进行偏移

str Rd , [基地址],偏移量

将目标寄存器到数据写入以基地址为首地址的内存中,然后基地址增加偏移量

ldr Rd , [基地址], 偏移量

从以基地址为首地址的内存中读取数据保存到目标寄存器中,然后将基地址增加偏移量的大小

自动索引:以基地址偏移后为首地址进行读写,同时基地址也进行自增自减

str Rd ,  [基地址,偏移量]!

将基地址自增偏移量大小,再将Rd的数据写入到以基地址为首地址的内存中

ldr Rd,[基地址,偏移量]!

先将基地址自增偏移量大小,再从基地址为首地址到内存中读取数据保存到Rd中

注:基地址要保存到一个寄存器中,偏移量要是一个立即数

 

此外还可以通过寄存器列表对内存批量读写

写:

stm 基地址, { 寄存器列表}

将寄存器列表中的所有寄存器数据写入到以基地址为首地址的内存中

读:

ldm 基地址,{寄存器列表}

从基地址开始往下读取数据,保存到寄存器列表中的每一个寄存器中

注:

         寄存器的写法有:起始寄存器-终止寄存器 /寄存器1、寄存器2、、、、

         并且无论寄存器列表编号顺序与否排列,内存读写始终是从小编号寄存器对应着低地址的数据

批量寄存器地址的增长方式有以下四种

ia、ib、da、db

 a:先读写,基地址再增长

b:基地址先增长,再进行读写

i:基地址往大地址方向增长

d:基地址往小地址方向增长

栈内存读写

1.空栈和满栈(E&F)

2.增栈和减栈(A&D)

也就形成了四类栈,空增(EA)空减(ED)满增(FA)满减(FD)

ARM默认使用满减栈(FD)

"交叉读写"即:ia写那就db读

对于ARM,满减是由ib写入那么就需要用da读出(对应满减栈就是先读再偏移)

满减栈的实现主要通过三种方式:压栈出栈、strdb和满减栈专用的后缀fd

1.压栈出栈

push {寄存器列表}

pop {寄存器列表}

start:

mov sp ,#0x40000020  @初始化的栈

mov R1, #0x1

mov r2,#0x2

mov r3,#0x3

push {R1-r5}

2.stmdb

将上述代码的push替换成stmdb

3.stmfd(满减专用)

push换成stmfd

最后就是关于叶子函数和非叶子函数的压栈出栈注意事项

关于叶子函数,为了叶子函数在操作寄存器时,不改变非叶子函数的需求,通常将从非叶子函数中已经使用且叶子函数中要使用寄存器数据进行压栈处理,在叶子函数处理完之后进行出栈释放,从而保证函数返回后寄存器的值和调用函数前的保持一致

针对于非叶子函数,还要额外的将返回地址进行压栈出栈处理将LR寄存器压栈非叶子函数调用完成后将其中 的地址数据出栈于sp寄存器中使程序继续正常运行

核心即压栈保护现场push{}出栈恢复现场pop{}


1.2.8状态寄存器传送指令

读取状态寄存器

mrs Rd,cpsr

读取CPSR的数值,保存到Rd中

修改状态寄存器

MSR cpsr , sh~

修改cpsr寄存器的数值为操作数

注:在特权模式下可以通过修改CPSR到非特权模式(USER模式),但是非特权模式不能通过修改cpsr寄存器的数值实现转化为特权模式,只有当对应的特权事件发生之后,处理器会自动进入对应的特权模式

1.2.9异常产生指令

1.2.9.1软中断产生指令

当软中断产生指令执行后会产生一个如饭中断,让处理器进入SVC模式下进行软中断的处理

swi  sh~

sh~是一个立即数即产生软中断的中断号

例子

start:

MRS r0 ,  cpsr @

Msr cpsr,#0x1

swi 1

loop

b loop

end

1.2.9.2异常模式和异常源

前者时处理器发生异常后进入的工作模式,后者是引发处理器产生异常的源头

总共分为五种异常模式和7种异常源

异常向量表:

ARM处理器在处理异常时采用了异常向量机制,通过在内存中申请一段空间为异常向量表,作为异常处理程序的索引项,根据索引项进入异常处理程序去执行。

cortex——a处理器的异常向量表时32字节,平分为8份。每一份时44字节,正好对应一条汇编指令,每一种异常源都会在异常向量表中有一个位置,剩下一份位置保留

1.2.9.3异常的处理(4⃣️大步3⃣️小步)

1.保存cpsr于spsr

2.修改cpsr(三小步) 

        修改为对应的异常模式【4;0】

        修改工作状态为ARM状态【5】-》0

         根据当前的异常的优先级禁用中断【7:6】

3.保存程序的返回地址到异常模式的LR寄存器中

4.修改PC的值到对应异常在异常向量表中的位置

1.2.9.4异常的返回

注:异常的返回必须要手动返回

1.将异常模式下的spsr数值赋值给cpsr,恢复程序的状态

2.将异常模式下的LR的数值赋值给PC,恢复程序执行的位置


1.2.10协处理器指令

2.伪操作:能够在编译过程中起到编译引导作用的 内容

.test  .gloabal  .if   .else   ..endif    .  .....

3.伪指令:不是汇编指令,但是可以起到指令的作用,也会占用一定的内存空间

4.注释

单行注释:@ 或 ;

多行注释:/**/

条件注释:

.if  逻辑值

        指令段

.else  

        指令段

.endif

5.混合编程

目的:使c语言资源和汇编资源相互调用

要求:符合ATPCS规范,将变量传递给从低到高的寄存器实现二者之间的相互调用

函数与标签:函数名汇编中当标签使用,标签c语言中当函数名使用

内联汇编格式

asm volatile(

"汇编指令\n\t"

。。。。。。

输出列表

输入列表

破坏列表

);
 

 

 


 

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

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

相关文章

学习ASP.NET Core的身份认证(基于JwtBearer的身份认证10)

基于Cookie传递token的主要思路是通过用户身份验证后&#xff0c;将生成的token保存到Response.Cookies返回客户端&#xff0c;后续客户端访问服务接口时会自动携带Cookie到服务端以便验证身份。之前一直搞不清楚的是服务端程序如何从Cookie读取token进行认证&#xff08;一般都…

Ollama 运行从 ModelScope 下载的 GGUF 格式的模型

本文系统环境 Windows 10 Ollama 0.5.7 Ollama 是什么&#xff1f; Ollama 可以让你快速集成和部署本地 AI 模型。它支持各种不同的 AI 模型&#xff0c;并允许用户通过简单的 API 进行调用 Ollama 的安装 Ollama 官网 有其下载及安装方法&#xff0c;非常简便 但如果希…

SpringBoot 整合 SSM

文章目录 SpringBoot 整合 SSM第一步&#xff1a;使用 Spring Initializr 创建项目第二步&#xff1a;现在配置类中配置数据库第三步&#xff1a;进行 MyBatis 相关操作编写数据表对应的实体类创建 mapper 接口利用 MyBaitsX 插件快速创建 xml 文件创建 Mapper 接口 SQL 实现在…

护眼好帮手:Windows显示器调节工具

在长时间使用电脑的过程中&#xff0c;显示器的亮度和色温对眼睛的舒适度有着重要影响。传统的显示器调节方式不仅操作繁琐&#xff0c;而且在低亮度下容易导致色彩失真。因此&#xff0c;今天我想为大家介绍一款适用于Windows系统的护眼工具&#xff0c;它可以帮助你轻松调节显…

基于Python的人工智能患者风险评估预测模型构建与应用研究(下)

3.3 模型选择与训练 3.3.1 常见预测模型介绍 在构建患者风险评估模型时,选择合适的预测模型至关重要。不同的模型具有各自的优缺点和适用场景,需要根据医疗数据的特点、风险评估的目标以及计算资源等因素进行综合考虑。以下详细介绍几种常见的预测模型。 逻辑回归(Logisti…

【NLP251】意图识别 与 Seq2Seq

Seq2Seq模型作为从RNN演进到Transformer和Attention机制的关键中间阶段&#xff0c;它不仅承前启后&#xff0c;还为我们深入理解这些复杂的模型架构提供了重要的基础。接下来&#xff0c;我们将详细探讨Seq2Seq模型的原理及其在自然语言处理领域中的应用。 1. 原理及网络框架 …

(长期更新)《零基础入门 ArcGIS(ArcMap) 》实验六----流域综合处理(超超超详细!!!)

流域综合处理 流域综合治理是根据流域自然和社会经济状况及区域国民经济发展的要求,以流域水流失治理为中心,以提高生态经济效益和社会经济持续发展为目标,以基本农田优化结构和高效利用及植被建设为重点,建立具有水土保持兼高效生态经济功能的半山区流域综合治理模式。数字高程…

unity使用内置videoplayer打包到安卓手机进行视频播放

1.新建UI&#xff0c;新建RawImage在画布当作视频播放的显示载体 2.新建VideoPlayer 3.新建Render Texture作为连接播放器视频显示和幕布的渲染纹理 将Render Texture同时挂载在VideoPlayer播放器和RawImage上。这样就可以将显示的视频内容在RawImage上显示出来了。 问题在于&a…

WPS mathtype间距太大、显示不全、公式一键改格式/大小

1、间距太大 用mathtype后行距变大的原因 mathtype行距变大到底怎么解决-MathType中文网 段落设置固定值 2、显示不全 设置格式&#xff1a; 打开MathType编辑器点击菜单栏中的"格式(Format)"选择"间距(Spacing)"在弹出的对话框中调整"分数间距(F…

堆的存储(了解)

由于堆是⼀个完全⼆叉树&#xff0c;因此可以⽤⼀个数组来存储。&#xff08;如果不清楚大家可以回顾⼆叉树的存储&#xff08;上&#xff09;c文章里的顺序存储&#xff09; 结点下标为 i &#xff1a; 如果⽗存在&#xff0c;⽗下标为 i/2 &#xff1b; 如果左孩⼦存在&…

数据结构 前缀中缀后缀

目录 前言 一&#xff0c;前缀中缀后缀的基本概念 二&#xff0c;前缀与后缀表达式 三&#xff0c;使用栈实现后缀 四&#xff0c;由中缀到后缀 总结 前言 这里学习前缀中缀后缀为我们学习树和图做准备&#xff0c;这个主题主要是对于算术和逻辑表达式求值&#xff0c;这…

【RocketMQ 存储】- broker 端存储单条消息的逻辑

文章目录 1. 前言2. DefaultMessageStore#asyncPutMessage 添加单条消息2.1 DefaultMessageStore#checkStoreStatus 检查存储服务的状态2.2 DefaultMessageStore#checkMessage 校验消息长度是否合法2.3 CommitLog#asyncPutMessage 核心存储逻辑2.4 MappedFile#appendMessage2.5…

Linux文件原生操作

Linux 中一切皆文件&#xff0c;那么 Linux 文件是什么&#xff1f; 在 Linux 中的文件 可以是&#xff1a;传统意义上的有序数据集合&#xff0c;即&#xff1a;文件系统中的物理文件 也可以是&#xff1a;设备&#xff0c;管道&#xff0c;内存。。。(Linux 管理的一切对象…

(undone) MIT6.S081 2023 学习笔记 (Day7: LAB6 Multithreading)

网页&#xff1a;https://pdos.csail.mit.edu/6.S081/2023/labs/thread.html 任务1&#xff1a;Uthread: switching between threads (moderate) (doing) 在这个练习中&#xff0c;你将设计一个用户级线程系统中的上下文切换机制&#xff0c;并实现它。为了帮助你开始&#xf…

Zookeeper入门部署(单点与集群)

本篇文章基于docker方式部署zookeeper集群&#xff0c;请先安装docker 目录 1. docker初期准备 2.启动zookeeper 2.1 单点部署 2.2 集群部署 3. Linux脚本实现快速切换启动关闭 1. docker初期准备 拉取zookeeper镜像 docker pull zookeeper:3.5.6 如果拉取时间过长&#xf…

【AI非常道】二零二五年一月(二),AI非常道

经常在社区看到一些非常有启发或者有收获的话语&#xff0c;但是&#xff0c;往往看过就成为过眼云烟&#xff0c;有时再想去找又找不到。索性&#xff0c;今年开始&#xff0c;看到好的言语&#xff0c;就记录下来&#xff0c;一月一发布&#xff0c;亦供大家参考。 有关AI非…

jQuery小游戏(二)

jQuery小游戏&#xff08;二&#xff09; 今天是新年的第二天&#xff0c;本人在这里祝大家&#xff0c;新年快乐&#xff0c;万事胜意&#x1f495; 紧接jQuery小游戏&#xff08;一&#xff09;的内容&#xff0c;我们开始继续往下咯&#x1f61c; 游戏中使用到的方法 key…

【硬件测试】基于FPGA的QPSK+帧同步系统开发与硬件片内测试,包含高斯信道,误码统计,可设置SNR

目录 1.算法仿真效果 2.算法涉及理论知识概要 2.1QPSK 2.2 帧同步 3.Verilog核心程序 4.开发板使用说明和如何移植不同的开发板 5.完整算法代码文件获得 1.算法仿真效果 本文是之前写的文章 《基于FPGA的QPSK帧同步系统verilog开发,包含testbench,高斯信道,误码统计,可…

NVIDIA GPU介绍:概念、序列、核心、A100、H100

概述 入职一家大模型领域创业公司&#xff0c;恶补相关知识。 概念 一些概念&#xff1a; HPC&#xff1a;High Performance Computing&#xff0c;高性能计算SoC&#xff1a;System on Chip&#xff0c;单片系统FLOPS&#xff1a;Floating Point Operations Per Second&am…

C++ list 容器用法

C list 容器用法 C 标准库提供了丰富的功能&#xff0c;其中 <list> 是一个非常重要的容器类&#xff0c;用于存储元素集合&#xff0c;支持双向迭代器。<list> 是 C 标准模板库&#xff08;STL&#xff09;中的一个序列容器&#xff0c;它允许在容器的任意位置快速…